home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / bash-1.12 / dist / y.tab.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-25  |  105.6 KB  |  3,796 lines

  1.  
  2. /*  A Bison parser, made from parse.y  */
  3.  
  4. #define    IF    258
  5. #define    THEN    259
  6. #define    ELSE    260
  7. #define    ELIF    261
  8. #define    FI    262
  9. #define    CASE    263
  10. #define    ESAC    264
  11. #define    FOR    265
  12. #define    WHILE    266
  13. #define    UNTIL    267
  14. #define    DO    268
  15. #define    DONE    269
  16. #define    FUNCTION    270
  17. #define    IN    271
  18. #define    BANG    272
  19. #define    WORD    273
  20. #define    NUMBER    274
  21. #define    AND_AND    275
  22. #define    OR_OR    276
  23. #define    GREATER_GREATER    277
  24. #define    LESS_LESS    278
  25. #define    LESS_AND    279
  26. #define    GREATER_AND    280
  27. #define    SEMI_SEMI    281
  28. #define    LESS_LESS_MINUS    282
  29. #define    AND_GREATER    283
  30. #define    LESS_GREATER    284
  31. #define    GREATER_BAR    285
  32. #define    yacc_EOF    286
  33.  
  34. #line 21 "parse.y"
  35.  
  36. #include <stdio.h>
  37. #include <sys/types.h>
  38. #include <signal.h>
  39. #include "shell.h"
  40. #include "flags.h"
  41. #include "input.h"
  42.  
  43. #if defined (READLINE)
  44. #include <readline/readline.h>
  45. #endif /* READLINE */
  46.  
  47. #include <readline/history.h>
  48.  
  49. #if defined (JOB_CONTROL)
  50. #  include "jobs.h"
  51. #endif /* JOB_CONTROL */
  52.  
  53. #define YYDEBUG 1
  54. extern int eof_encountered;
  55. extern int no_line_editing;
  56. extern int interactive, interactive_shell;
  57.  
  58. /* **************************************************************** */
  59. /*                                    */
  60. /*            "Forward" declarations                */
  61. /*                                    */
  62. /* **************************************************************** */
  63.  
  64. /* This is kind of sickening.  In order to let these variables be seen by
  65.    all the functions that need them, I am forced to place their declarations
  66.    far away from the place where they should logically be found. */
  67.  
  68. static int reserved_word_acceptable ();
  69.  
  70. /* PROMPT_STRING_POINTER points to one of these, never to an actual string. */
  71. char *ps1_prompt, *ps2_prompt;
  72.  
  73. /* Handle on the current prompt string.  Indirectly points through
  74.    ps1_ or ps2_prompt. */
  75. char **prompt_string_pointer = (char **)NULL;
  76. char *current_prompt_string;
  77.  
  78. /* The number of lines read from input while creating the current command. */
  79. int current_command_line_count = 0;
  80.  
  81. /* Variables to manage the task of reading here documents, because we need to
  82.    defer the reading until after a complete command has been collected. */
  83. REDIRECT *redirection_needing_here_doc = (REDIRECT *)NULL;
  84. int need_here_doc = 0;
  85.  
  86. #line 73 "parse.y"
  87. typedef union {
  88.   WORD_DESC *word;        /* the word that we read. */
  89.   int number;            /* the number that we read. */
  90.   WORD_LIST *word_list;
  91.   COMMAND *command;
  92.   REDIRECT *redirect;
  93.   ELEMENT element;
  94.   PATTERN_LIST *pattern;
  95. } YYSTYPE;
  96.  
  97. #ifndef YYLTYPE
  98. typedef
  99.   struct yyltype
  100.     {
  101.       int timestamp;
  102.       int first_line;
  103.       int first_column;
  104.       int last_line;
  105.       int last_column;
  106.       char *text;
  107.    }
  108.   yyltype;
  109.  
  110. #define YYLTYPE yyltype
  111. #endif
  112.  
  113. #include <stdio.h>
  114.  
  115. #ifndef __STDC__
  116. #define const
  117. #endif
  118.  
  119.  
  120.  
  121. #define    YYFINAL        228
  122. #define    YYFLAG        -32768
  123. #define    YYNTBASE    43
  124.  
  125. #define YYTRANSLATE(x) ((unsigned)(x) <= 286 ? yytranslate[x] : 68)
  126.  
  127. static const char yytranslate[] = {     0,
  128.      2,     2,     2,     2,     2,     2,     2,     2,     2,    33,
  129.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  130.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  131.      2,     2,     2,     2,     2,     2,     2,    31,     2,    41,
  132.     42,     2,     2,     2,    38,     2,     2,     2,     2,     2,
  133.      2,     2,     2,     2,     2,     2,     2,     2,    32,    37,
  134.      2,    36,     2,     2,     2,     2,     2,     2,     2,     2,
  135.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  136.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  137.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  138.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  139.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  140.      2,     2,    39,    35,    40,     2,     2,     2,     2,     2,
  141.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  142.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  143.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  144.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  145.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  146.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  147.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  148.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  149.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  150.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  151.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  152.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  153.      2,     2,     2,     2,     2,     1,     2,     3,     4,     5,
  154.      6,     7,     8,     9,    10,    11,    12,    13,    14,    15,
  155.     16,    17,    18,    19,    20,    21,    22,    23,    24,    25,
  156.     26,    27,    28,    29,    30,    34
  157. };
  158.  
  159. static const short yyprhs[] = {     0,
  160.      0,     3,     5,     8,    10,    11,    14,    17,    20,    24,
  161.     28,    31,    35,    38,    42,    45,    49,    52,    56,    59,
  162.     63,    66,    70,    73,    77,    80,    84,    87,    91,    94,
  163.     98,   101,   104,   108,   110,   112,   114,   117,   119,   122,
  164.    124,   126,   128,   131,   134,   141,   148,   156,   164,   175,
  165.    186,   193,   201,   208,   210,   216,   222,   226,   228,   234,
  166.    241,   246,   252,   260,   267,   271,   276,   283,   289,   291,
  167.    294,   299,   304,   310,   316,   318,   321,   327,   333,   340,
  168.    347,   349,   353,   356,   358,   362,   366,   370,   375,   380,
  169.    385,   390,   395,   397,   400,   402,   404,   406,   407,   410,
  170.    412,   415,   418,   423,   428,   432,   436,   438,   441,   446
  171. };
  172.  
  173. static const short yyrhs[] = {    65,
  174.     33,     0,    33,     0,     1,    33,     0,    34,     0,     0,
  175.     44,    18,     0,    36,    18,     0,    37,    18,     0,    19,
  176.     36,    18,     0,    19,    37,    18,     0,    22,    18,     0,
  177.     19,    22,    18,     0,    23,    18,     0,    19,    23,    18,
  178.      0,    24,    19,     0,    19,    24,    19,     0,    25,    19,
  179.      0,    19,    25,    19,     0,    24,    18,     0,    19,    24,
  180.     18,     0,    25,    18,     0,    19,    25,    18,     0,    27,
  181.     18,     0,    19,    27,    18,     0,    25,    38,     0,    19,
  182.     25,    38,     0,    24,    38,     0,    19,    24,    38,     0,
  183.     28,    18,     0,    19,    29,    18,     0,    29,    18,     0,
  184.     30,    18,     0,    19,    30,    18,     0,    18,     0,    45,
  185.      0,    45,     0,    47,    45,     0,    46,     0,    48,    46,
  186.      0,    48,     0,    50,     0,    51,     0,    51,    47,     0,
  187.     47,    51,     0,    10,    18,    64,    13,    60,    14,     0,
  188.     10,    18,    64,    39,    60,    40,     0,    10,    18,    32,
  189.     64,    13,    60,    14,     0,    10,    18,    32,    64,    39,
  190.     60,    40,     0,    10,    18,    64,    16,    44,    63,    64,
  191.     13,    60,    14,     0,    10,    18,    64,    16,    44,    63,
  192.     64,    39,    60,    40,     0,     8,    18,    64,    16,    64,
  193.      9,     0,     8,    18,    64,    16,    57,    64,     9,     0,
  194.      8,    18,    64,    16,    55,     9,     0,    52,     0,    11,
  195.     60,    13,    60,    14,     0,    12,    60,    13,    60,    14,
  196.      0,    41,    60,    42,     0,    53,     0,    18,    41,    42,
  197.     64,    53,     0,    15,    18,    41,    42,    64,    53,     0,
  198.     15,    18,    64,    53,     0,     3,    60,     4,    60,     7,
  199.      0,     3,    60,     4,    60,     5,    60,     7,     0,     3,
  200.     60,     4,    60,    54,     7,     0,    39,    60,    40,     0,
  201.      6,    60,     4,    60,     0,     6,    60,     4,    60,     5,
  202.     60,     0,     6,    60,     4,    60,    54,     0,    56,     0,
  203.     57,    56,     0,    64,    59,    42,    60,     0,    64,    59,
  204.     42,    64,     0,    64,    41,    59,    42,    60,     0,    64,
  205.     41,    59,    42,    64,     0,    58,     0,    57,    58,     0,
  206.     64,    59,    42,    60,    26,     0,    64,    59,    42,    64,
  207.     26,     0,    64,    41,    59,    42,    60,    26,     0,    64,
  208.     41,    59,    42,    64,    26,     0,    18,     0,    59,    35,
  209.     18,     0,    64,    61,     0,    62,     0,    62,    33,    64,
  210.      0,    62,    31,    64,     0,    62,    32,    64,     0,    62,
  211.     20,    64,    62,     0,    62,    21,    64,    62,     0,    62,
  212.     31,    64,    62,     0,    62,    32,    64,    62,     0,    62,
  213.     33,    64,    62,     0,    67,     0,    17,    67,     0,    33,
  214.      0,    32,     0,    34,     0,     0,    64,    33,     0,    66,
  215.      0,    66,    31,     0,    66,    32,     0,    66,    20,    64,
  216.     66,     0,    66,    21,    64,    66,     0,    66,    31,    66,
  217.      0,    66,    32,    66,     0,    67,     0,    17,    67,     0,
  218.     67,    35,    64,    67,     0,    49,     0
  219. };
  220.  
  221. #if YYDEBUG != 0
  222. static const short yyrline[] = { 0,
  223.    114,   123,   130,   146,   156,   158,   162,   164,   166,   168,
  224.    170,   172,   174,   180,   186,   190,   194,   198,   202,   207,
  225.    212,   217,   222,   229,   236,   238,   240,   242,   244,   246,
  226.    248,   258,   260,   264,   266,   270,   274,   285,   287,   291,
  227.    293,   297,   299,   302,   306,   308,   310,   312,   315,   317,
  228.    320,   322,   324,   329,   331,   333,   336,   339,   342,   345,
  229.    348,   352,   354,   356,   361,   365,   367,   369,   373,   374,
  230.    378,   380,   382,   384,   388,   390,   394,   396,   398,   400,
  231.    404,   406,   415,   424,   425,   426,   428,   432,   434,   436,
  232.    438,   440,   442,   444,   451,   452,   453,   456,   457,   466,
  233.    473,   480,   489,   491,   493,   495,   497,   499,   506,   509
  234. };
  235.  
  236. static const char * const yytname[] = {   "$",
  237. "error","$illegal.","IF","THEN","ELSE","ELIF","FI","CASE","ESAC","FOR",
  238. "WHILE","UNTIL","DO","DONE","FUNCTION","IN","BANG","WORD","NUMBER","AND_AND",
  239. "OR_OR","GREATER_GREATER","LESS_LESS","LESS_AND","GREATER_AND","SEMI_SEMI","LESS_LESS_MINUS","AND_GREATER","LESS_GREATER","GREATER_BAR",
  240. "'&'","';'","'\\n'","yacc_EOF","'|'","'>'","'<'","'-'","'{'","'}'",
  241. "'('","')'","inputunit","words","redirection","simple_command_element","redirections","simple_command","command","shell_command",
  242. "shell_command_1","if_command","group_command","elif_clause","case_clause_1","pattern_list_1","case_clause_sequence","pattern_list","pattern","list",
  243. "list0","list1","list_terminator","newlines","simple_list","simple_list1","pipeline",""
  244. };
  245. #endif
  246.  
  247. static const short yyr1[] = {     0,
  248.     43,    43,    43,    43,    44,    44,    45,    45,    45,    45,
  249.     45,    45,    45,    45,    45,    45,    45,    45,    45,    45,
  250.     45,    45,    45,    45,    45,    45,    45,    45,    45,    45,
  251.     45,    45,    45,    46,    46,    47,    47,    48,    48,    49,
  252.     49,    50,    50,    50,    51,    51,    51,    51,    51,    51,
  253.     51,    51,    51,    51,    51,    51,    51,    51,    51,    51,
  254.     51,    52,    52,    52,    53,    54,    54,    54,    55,    55,
  255.     56,    56,    56,    56,    57,    57,    58,    58,    58,    58,
  256.     59,    59,    60,    61,    61,    61,    61,    62,    62,    62,
  257.     62,    62,    62,    62,    63,    63,    63,    64,    64,    65,
  258.     65,    65,    66,    66,    66,    66,    66,    66,    67,    67
  259. };
  260.  
  261. static const short yyr2[] = {     0,
  262.      2,     1,     2,     1,     0,     2,     2,     2,     3,     3,
  263.      2,     3,     2,     3,     2,     3,     2,     3,     2,     3,
  264.      2,     3,     2,     3,     2,     3,     2,     3,     2,     3,
  265.      2,     2,     3,     1,     1,     1,     2,     1,     2,     1,
  266.      1,     1,     2,     2,     6,     6,     7,     7,    10,    10,
  267.      6,     7,     6,     1,     5,     5,     3,     1,     5,     6,
  268.      4,     5,     7,     6,     3,     4,     6,     5,     1,     2,
  269.      4,     4,     5,     5,     1,     2,     5,     5,     6,     6,
  270.      1,     3,     2,     1,     3,     3,     3,     4,     4,     4,
  271.      4,     4,     1,     2,     1,     1,     1,     0,     2,     1,
  272.      2,     2,     4,     4,     3,     3,     1,     2,     4,     1
  273. };
  274.  
  275. static const short yydefact[] = {     0,
  276.      0,    98,     0,     0,    98,    98,     0,     0,    34,     0,
  277.      0,     0,     0,     0,     0,     0,     0,     0,     2,     4,
  278.      0,     0,    98,    98,    35,    38,     0,    40,   110,    41,
  279.     42,    54,    58,     0,   100,   107,     3,     0,     0,    98,
  280.     98,     0,     0,    98,   108,     0,     0,     0,     0,     0,
  281.      0,     0,     0,     0,     0,    11,    13,    19,    15,    27,
  282.     21,    17,    25,    23,    29,    31,    32,     7,     8,     0,
  283.      0,     0,    37,    44,    34,    35,    39,    36,    43,     1,
  284.     98,    98,   101,   102,    98,    98,     0,    99,    83,    84,
  285.     93,     0,    98,     0,    98,    98,     0,     0,    98,    12,
  286.     14,    20,    16,    28,    22,    18,    26,    24,    30,    33,
  287.      9,    10,    65,    57,     0,     0,   105,   106,     0,     0,
  288.     94,    98,    98,    98,    98,    98,    98,     0,    98,     5,
  289.     98,     0,     0,    98,    61,     0,   103,   104,     0,     0,
  290.    109,    98,    98,    62,     0,     0,     0,    86,    87,    85,
  291.      0,    69,    98,    75,     0,    98,    98,     0,     0,     0,
  292.     55,    56,     0,    59,     0,     0,    64,    88,    89,    90,
  293.     91,    92,    53,    70,    76,     0,    51,    81,     0,     0,
  294.      0,     0,    45,     6,    96,    95,    97,    98,    46,    60,
  295.     63,    98,    98,    98,    98,    52,     0,     0,    98,    47,
  296.     48,     0,    66,     0,     0,     0,    98,    82,    71,    72,
  297.     98,    98,    98,    68,    73,    74,    77,    78,     0,     0,
  298.     67,    79,    80,    49,    50,     0,     0,     0
  299. };
  300.  
  301. static const short yydefgoto[] = {   226,
  302.    159,    25,    26,    27,    28,    29,    30,    31,    32,    33,
  303.    145,   151,   152,   153,   154,   180,    38,    89,    90,   188,
  304.     39,    34,   117,    91
  305. };
  306.  
  307. static const short yypact[] = {   202,
  308.    -18,-32768,     9,    23,-32768,-32768,    31,   394,    10,   466,
  309.     38,    44,    35,    56,    54,    74,    77,    87,-32768,-32768,
  310.     92,   100,-32768,-32768,    18,-32768,   426,   450,-32768,-32768,
  311.     84,-32768,-32768,    86,    96,    88,-32768,   118,   266,-32768,
  312.    102,   135,   136,   121,    88,   128,   145,   154,    61,    64,
  313.    158,   159,   170,   172,   173,-32768,-32768,-32768,-32768,-32768,
  314. -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,   160,
  315.    157,    10,-32768,-32768,-32768,-32768,-32768,-32768,    84,-32768,
  316. -32768,-32768,   330,   330,-32768,-32768,   394,-32768,-32768,   111,
  317.     88,     1,-32768,    19,-32768,-32768,   162,     7,-32768,-32768,
  318. -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
  319. -32768,-32768,-32768,-32768,   298,   298,     3,     3,   362,   140,
  320.     88,-32768,-32768,-32768,-32768,-32768,-32768,    -8,-32768,-32768,
  321. -32768,   182,   184,-32768,-32768,     7,-32768,-32768,   330,   330,
  322.     88,-32768,-32768,-32768,   194,   266,   266,   266,   266,   266,
  323.    200,-32768,-32768,-32768,    27,-32768,-32768,   197,   107,   175,
  324. -32768,-32768,     7,-32768,   209,   214,-32768,-32768,-32768,    17,
  325.     17,    17,-32768,-32768,-32768,    30,-32768,-32768,   204,    58,
  326.    219,   183,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
  327. -32768,-32768,-32768,-32768,-32768,-32768,   123,   210,-32768,-32768,
  328. -32768,    37,    72,   266,   266,   266,-32768,-32768,   208,   156,
  329. -32768,-32768,-32768,-32768,   221,   234,-32768,-32768,   226,   215,
  330. -32768,-32768,-32768,-32768,-32768,   248,   250,-32768
  331. };
  332.  
  333. static const short yypgoto[] = {-32768,
  334. -32768,   -15,   237,   223,-32768,-32768,-32768,   239,-32768,   -94,
  335.     65,-32768,   119,-32768,   126,   101,    -5,-32768,  -139,-32768,
  336.    -38,-32768,    20,    14
  337. };
  338.  
  339.  
  340. #define    YYLAST        503
  341.  
  342.  
  343. static const short yytable[] = {    42,
  344.     43,    92,    94,   135,   156,    98,   168,   169,   170,   171,
  345.    172,    73,    76,    36,    37,    78,   127,    70,    71,    35,
  346.    -36,    45,    81,    82,    88,   -36,    40,   -36,   -36,   -36,
  347.    157,   129,   -36,    88,   130,   177,   122,   123,   196,    88,
  348.     41,   164,   115,   116,   178,    23,   119,   178,    44,   211,
  349.     46,    88,    58,    59,   128,    56,   -36,   131,   -36,    88,
  350.    136,    57,    88,    73,   170,   171,   172,   179,   190,    88,
  351.    179,    64,    60,    61,    62,   212,   213,   143,   102,   103,
  352.    120,   105,   106,   146,   147,   148,   149,   150,   155,   132,
  353.    133,    65,   198,    63,    66,   163,    36,    36,   104,   199,
  354.    121,   107,    10,   118,    67,    11,    12,    13,    14,    68,
  355.     15,    16,    17,    18,   176,    81,    82,    69,    80,    21,
  356.     22,    86,    85,   158,   184,   160,    83,    84,    36,    36,
  357.    122,   123,   141,    93,   137,   138,   165,   166,   185,   186,
  358.    187,   124,   125,   126,   142,   143,   144,    95,    96,   202,
  359.    181,   182,    36,    36,   204,   205,   206,   198,     2,   118,
  360.    210,    97,   100,     3,   207,     4,     5,     6,   216,    99,
  361.      7,   101,    87,     9,    10,   108,   109,    11,    12,    13,
  362.     14,   218,    15,    16,    17,    18,   203,   110,    88,   111,
  363.    112,    21,    22,   209,    23,   161,    24,   162,   114,   113,
  364.    167,   215,     1,   134,     2,   219,   220,   221,   173,     3,
  365.    183,     4,     5,     6,   189,   191,     7,   192,     8,     9,
  366.     10,   178,   201,    11,    12,    13,    14,   208,    15,    16,
  367.     17,    18,   200,   217,    19,    20,     2,    21,    22,   224,
  368.     23,     3,    24,     4,     5,     6,   222,   227,     7,   228,
  369.     87,     9,    10,    79,   225,    11,    12,    13,    14,   223,
  370.     15,    16,    17,    18,    77,    74,    88,   214,     2,    21,
  371.     22,   174,    23,     3,    24,     4,     5,     6,   175,   197,
  372.      7,     0,    87,     9,    10,     0,     0,    11,    12,    13,
  373.     14,     0,    15,    16,    17,    18,     0,     0,    88,     0,
  374.      2,    21,    22,     0,    23,     3,    24,     4,     5,     6,
  375.      0,     0,     7,     0,     8,     9,    10,     0,     0,    11,
  376.     12,    13,    14,     0,    15,    16,    17,    18,     0,     0,
  377.     88,     0,     2,    21,    22,     0,    23,     3,    24,     4,
  378.      5,     6,     0,     0,     7,     0,     8,     9,    10,     0,
  379.      0,    11,    12,    13,    14,     0,    15,    16,    17,    18,
  380.      0,     0,     0,     0,     2,    21,    22,     0,    23,     3,
  381.     24,     4,     5,     6,     0,     0,     7,     0,     0,     9,
  382.     10,     0,     0,    11,    12,    13,    14,     0,    15,    16,
  383.     17,    18,     0,     0,    88,     0,     2,    21,    22,     0,
  384.     23,     3,    24,     4,     5,     6,     0,     0,     7,     0,
  385.      0,     9,    10,     0,     0,    11,    12,    13,    14,     0,
  386.     15,    16,    17,    18,     0,     0,     0,     0,     2,    21,
  387.     22,     0,    23,     3,    24,     4,     5,     6,     0,     0,
  388.      7,     0,     0,    72,    10,     0,     0,    11,    12,    13,
  389.     14,     0,    15,    16,    17,    18,     0,     0,     0,     0,
  390.      0,    21,    22,     0,    23,     0,    24,    75,    10,     0,
  391.      0,    11,    12,    13,    14,     0,    15,    16,    17,    18,
  392.      0,     0,     0,     0,     0,    21,    22,    47,    48,    49,
  393.     50,     0,    51,     0,    52,    53,     0,     0,     0,     0,
  394.      0,    54,    55
  395. };
  396.  
  397. static const short yycheck[] = {     5,
  398.      6,    40,    41,    98,    13,    44,   146,   147,   148,   149,
  399.    150,    27,    28,     0,    33,    31,    16,    23,    24,     0,
  400.      3,     8,    20,    21,    33,     8,    18,    10,    11,    12,
  401.     39,    13,    15,    33,    16,     9,    20,    21,     9,    33,
  402.     18,   136,    81,    82,    18,    39,    85,    18,    18,    13,
  403.     41,    33,    18,    19,    93,    18,    39,    39,    41,    33,
  404.     99,    18,    33,    79,   204,   205,   206,    41,   163,    33,
  405.     41,    18,    38,    18,    19,    39,     5,     6,    18,    19,
  406.     86,    18,    19,   122,   123,   124,   125,   126,   127,    95,
  407.     96,    18,    35,    38,    18,   134,    83,    84,    38,    42,
  408.     87,    38,    19,    84,    18,    22,    23,    24,    25,    18,
  409.     27,    28,    29,    30,   153,    20,    21,    18,    33,    36,
  410.     37,     4,    35,   129,    18,   131,    31,    32,   115,   116,
  411.     20,    21,   119,    32,   115,   116,   142,   143,    32,    33,
  412.     34,    31,    32,    33,     5,     6,     7,    13,    13,   188,
  413.    156,   157,   139,   140,   193,   194,   195,    35,     3,   140,
  414.    199,    41,    18,     8,    42,    10,    11,    12,   207,    42,
  415.     15,    18,    17,    18,    19,    18,    18,    22,    23,    24,
  416.     25,    26,    27,    28,    29,    30,   192,    18,    33,    18,
  417.     18,    36,    37,   199,    39,    14,    41,    14,    42,    40,
  418.      7,   207,     1,    42,     3,   211,   212,   213,     9,     8,
  419.     14,    10,    11,    12,    40,     7,    15,     4,    17,    18,
  420.     19,    18,    40,    22,    23,    24,    25,    18,    27,    28,
  421.     29,    30,    14,    26,    33,    34,     3,    36,    37,    14,
  422.     39,     8,    41,    10,    11,    12,    26,     0,    15,     0,
  423.     17,    18,    19,    31,    40,    22,    23,    24,    25,    26,
  424.     27,    28,    29,    30,    28,    27,    33,   203,     3,    36,
  425.     37,   153,    39,     8,    41,    10,    11,    12,   153,   179,
  426.     15,    -1,    17,    18,    19,    -1,    -1,    22,    23,    24,
  427.     25,    -1,    27,    28,    29,    30,    -1,    -1,    33,    -1,
  428.      3,    36,    37,    -1,    39,     8,    41,    10,    11,    12,
  429.     -1,    -1,    15,    -1,    17,    18,    19,    -1,    -1,    22,
  430.     23,    24,    25,    -1,    27,    28,    29,    30,    -1,    -1,
  431.     33,    -1,     3,    36,    37,    -1,    39,     8,    41,    10,
  432.     11,    12,    -1,    -1,    15,    -1,    17,    18,    19,    -1,
  433.     -1,    22,    23,    24,    25,    -1,    27,    28,    29,    30,
  434.     -1,    -1,    -1,    -1,     3,    36,    37,    -1,    39,     8,
  435.     41,    10,    11,    12,    -1,    -1,    15,    -1,    -1,    18,
  436.     19,    -1,    -1,    22,    23,    24,    25,    -1,    27,    28,
  437.     29,    30,    -1,    -1,    33,    -1,     3,    36,    37,    -1,
  438.     39,     8,    41,    10,    11,    12,    -1,    -1,    15,    -1,
  439.     -1,    18,    19,    -1,    -1,    22,    23,    24,    25,    -1,
  440.     27,    28,    29,    30,    -1,    -1,    -1,    -1,     3,    36,
  441.     37,    -1,    39,     8,    41,    10,    11,    12,    -1,    -1,
  442.     15,    -1,    -1,    18,    19,    -1,    -1,    22,    23,    24,
  443.     25,    -1,    27,    28,    29,    30,    -1,    -1,    -1,    -1,
  444.     -1,    36,    37,    -1,    39,    -1,    41,    18,    19,    -1,
  445.     -1,    22,    23,    24,    25,    -1,    27,    28,    29,    30,
  446.     -1,    -1,    -1,    -1,    -1,    36,    37,    22,    23,    24,
  447.     25,    -1,    27,    -1,    29,    30,    -1,    -1,    -1,    -1,
  448.     -1,    36,    37
  449. };
  450. /* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
  451. #line 3 "/usr/gnu/lib/bison.simple"
  452.  
  453. /* Skeleton output parser for bison,
  454.    Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman
  455.  
  456.    This program is free software; you can redistribute it and/or modify
  457.    it under the terms of the GNU General Public License as published by
  458.    the Free Software Foundation; either version 1, or (at your option)
  459.    any later version.
  460.  
  461.    This program is distributed in the hope that it will be useful,
  462.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  463.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  464.    GNU General Public License for more details.
  465.  
  466.    You should have received a copy of the GNU General Public License
  467.    along with this program; if not, write to the Free Software
  468.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  469.  
  470.  
  471. #ifndef alloca
  472. #ifdef __GNUC__
  473. #define alloca __builtin_alloca
  474. #else /* Not GNU C.  */
  475. #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__)
  476. #include <alloca.h>
  477. #else /* Not sparc */
  478. #ifdef MSDOS
  479. #include <malloc.h>
  480. #endif /* MSDOS */
  481. #endif /* Not sparc.  */
  482. #endif /* Not GNU C.  */
  483. #endif /* alloca not defined.  */
  484.  
  485. /* This is the parser code that is written into each bison parser
  486.   when the %semantic_parser declaration is not specified in the grammar.
  487.   It was written by Richard Stallman by simplifying the hairy parser
  488.   used when %semantic_parser is specified.  */
  489.  
  490. /* Note: there must be only one dollar sign in this file.
  491.    It is replaced by the list of actions, each action
  492.    as one case of the switch.  */
  493.  
  494. #define yyerrok        (yyerrstatus = 0)
  495. #define yyclearin    (yychar = YYEMPTY)
  496. #define YYEMPTY        -2
  497. #define YYEOF        0
  498. #define YYACCEPT    return(0)
  499. #define YYABORT     return(1)
  500. #define YYERROR        goto yyerrlab1
  501. /* Like YYERROR except do call yyerror.
  502.    This remains here temporarily to ease the
  503.    transition to the new meaning of YYERROR, for GCC.
  504.    Once GCC version 2 has supplanted version 1, this can go.  */
  505. #define YYFAIL        goto yyerrlab
  506. #define YYRECOVERING()  (!!yyerrstatus)
  507. #define YYBACKUP(token, value) \
  508. do                                \
  509.   if (yychar == YYEMPTY && yylen == 1)                \
  510.     { yychar = (token), yylval = (value);            \
  511.       yychar1 = YYTRANSLATE (yychar);                \
  512.       YYPOPSTACK;                        \
  513.       goto yybackup;                        \
  514.     }                                \
  515.   else                                \
  516.     { yyerror ("syntax error: cannot back up"); YYERROR; }    \
  517. while (0)
  518.  
  519. #define YYTERROR    1
  520. #define YYERRCODE    256
  521.  
  522. #ifndef YYPURE
  523. #define YYLEX        yylex()
  524. #endif
  525.  
  526. #ifdef YYPURE
  527. #ifdef YYLSP_NEEDED
  528. #define YYLEX        yylex(&yylval, &yylloc)
  529. #else
  530. #define YYLEX        yylex(&yylval)
  531. #endif
  532. #endif
  533.  
  534. /* If nonreentrant, generate the variables here */
  535.  
  536. #ifndef YYPURE
  537.  
  538. int    yychar;            /*  the lookahead symbol        */
  539. YYSTYPE    yylval;            /*  the semantic value of the        */
  540.                 /*  lookahead symbol            */
  541.  
  542. #ifdef YYLSP_NEEDED
  543. YYLTYPE yylloc;            /*  location data for the lookahead    */
  544.                 /*  symbol                */
  545. #endif
  546.  
  547. int yynerrs;            /*  number of parse errors so far       */
  548. #endif  /* not YYPURE */
  549.  
  550. #if YYDEBUG != 0
  551. int yydebug;            /*  nonzero means print parse trace    */
  552. /* Since this is uninitialized, it does not stop multiple parsers
  553.    from coexisting.  */
  554. #endif
  555.  
  556. /*  YYINITDEPTH indicates the initial size of the parser's stacks    */
  557.  
  558. #ifndef    YYINITDEPTH
  559. #define YYINITDEPTH 200
  560. #endif
  561.  
  562. /*  YYMAXDEPTH is the maximum size the stacks can grow to
  563.     (effective only if the built-in stack extension method is used).  */
  564.  
  565. #if YYMAXDEPTH == 0
  566. #undef YYMAXDEPTH
  567. #endif
  568.  
  569. #ifndef YYMAXDEPTH
  570. #define YYMAXDEPTH 10000
  571. #endif
  572.  
  573. #ifndef __cplusplus
  574.  
  575. /* This is the most reliable way to avoid incompatibilities
  576.    in available built-in functions on various systems.  */
  577. static void
  578. __yy_bcopy (from, to, count)
  579.      char *from;
  580.      char *to;
  581.      int count;
  582. {
  583.   register char *f = from;
  584.   register char *t = to;
  585.   register int i = count;
  586.  
  587.   while (i-- > 0)
  588.     *t++ = *f++;
  589. }
  590.  
  591. #else /* __cplusplus */
  592.  
  593. /* This is the most reliable way to avoid incompatibilities
  594.    in available built-in functions on various systems.  */
  595. static void
  596. __yy_bcopy (char *from, char *to, int count)
  597. {
  598.   register char *f = from;
  599.   register char *t = to;
  600.   register int i = count;
  601.  
  602.   while (i-- > 0)
  603.     *t++ = *f++;
  604. }
  605.  
  606. #endif
  607.  
  608. #line 160 "/usr/gnu/lib/bison.simple"
  609. int
  610. yyparse()
  611. {
  612.   register int yystate;
  613.   register int yyn;
  614.   register short *yyssp;
  615.   register YYSTYPE *yyvsp;
  616.   int yyerrstatus;    /*  number of tokens to shift before error messages enabled */
  617.   int yychar1;        /*  lookahead token as an internal (translated) token number */
  618.  
  619.   short    yyssa[YYINITDEPTH];    /*  the state stack            */
  620.   YYSTYPE yyvsa[YYINITDEPTH];    /*  the semantic value stack        */
  621.  
  622.   short *yyss = yyssa;        /*  refer to the stacks thru separate pointers */
  623.   YYSTYPE *yyvs = yyvsa;    /*  to allow yyoverflow to reallocate them elsewhere */
  624.  
  625. #ifdef YYLSP_NEEDED
  626.   YYLTYPE *yyls = yylsa;
  627.   YYLTYPE *yylsp;
  628.   YYLTYPE yylsa[YYINITDEPTH];    /*  the location stack            */
  629.  
  630. #define YYPOPSTACK   (yyvsp--, yysp--, yylsp--)
  631. #else
  632. #define YYPOPSTACK   (yyvsp--, yysp--)
  633. #endif
  634.  
  635.   int yystacksize = YYINITDEPTH;
  636.  
  637. #ifdef YYPURE
  638.   int yychar;
  639.   YYSTYPE yylval;
  640.   int yynerrs;
  641. #ifdef YYLSP_NEEDED
  642.   YYLTYPE yylloc;
  643. #endif
  644. #endif
  645.  
  646.   YYSTYPE yyval;        /*  the variable used to return        */
  647.                 /*  semantic values from the action    */
  648.                 /*  routines                */
  649.  
  650.   int yylen;
  651.  
  652. #if YYDEBUG != 0
  653.   if (yydebug)
  654.     fprintf(stderr, "Starting parse\n");
  655. #endif
  656.  
  657.   yystate = 0;
  658.   yyerrstatus = 0;
  659.   yynerrs = 0;
  660.   yychar = YYEMPTY;        /* Cause a token to be read.  */
  661.  
  662.   /* Initialize stack pointers.
  663.      Waste one element of value and location stack
  664.      so that they stay on the same level as the state stack.  */
  665.  
  666.   yyssp = yyss - 1;
  667.   yyvsp = yyvs;
  668. #ifdef YYLSP_NEEDED
  669.   yylsp = yyls;
  670. #endif
  671.  
  672. /* Push a new state, which is found in  yystate  .  */
  673. /* In all cases, when you get here, the value and location stacks
  674.    have just been pushed. so pushing a state here evens the stacks.  */
  675. yynewstate:
  676.  
  677.   *++yyssp = yystate;
  678.  
  679.   if (yyssp >= yyss + yystacksize - 1)
  680.     {
  681.       /* Give user a chance to reallocate the stack */
  682.       /* Use copies of these so that the &'s don't force the real ones into memory. */
  683.       YYSTYPE *yyvs1 = yyvs;
  684.       short *yyss1 = yyss;
  685. #ifdef YYLSP_NEEDED
  686.       YYLTYPE *yyls1 = yyls;
  687. #endif
  688.  
  689.       /* Get the current used size of the three stacks, in elements.  */
  690.       int size = yyssp - yyss + 1;
  691.  
  692. #ifdef yyoverflow
  693.       /* Each stack pointer address is followed by the size of
  694.      the data in use in that stack, in bytes.  */
  695.       yyoverflow("parser stack overflow",
  696.          &yyss1, size * sizeof (*yyssp),
  697.          &yyvs1, size * sizeof (*yyvsp),
  698. #ifdef YYLSP_NEEDED
  699.          &yyls1, size * sizeof (*yylsp),
  700. #endif
  701.          &yystacksize);
  702.  
  703.       yyss = yyss1; yyvs = yyvs1;
  704. #ifdef YYLSP_NEEDED
  705.       yyls = yyls1;
  706. #endif
  707. #else /* no yyoverflow */
  708.       /* Extend the stack our own way.  */
  709.       if (yystacksize >= YYMAXDEPTH)
  710.     {
  711.       yyerror("parser stack overflow");
  712.       return 2;
  713.     }
  714.       yystacksize *= 2;
  715.       if (yystacksize > YYMAXDEPTH)
  716.     yystacksize = YYMAXDEPTH;
  717.       yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
  718.       __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
  719.       yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
  720.       __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
  721. #ifdef YYLSP_NEEDED
  722.       yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
  723.       __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
  724. #endif
  725. #endif /* no yyoverflow */
  726.  
  727.       yyssp = yyss + size - 1;
  728.       yyvsp = yyvs + size - 1;
  729. #ifdef YYLSP_NEEDED
  730.       yylsp = yyls + size - 1;
  731. #endif
  732.  
  733. #if YYDEBUG != 0
  734.       if (yydebug)
  735.     fprintf(stderr, "Stack size increased to %d\n", yystacksize);
  736. #endif
  737.  
  738.       if (yyssp >= yyss + yystacksize - 1)
  739.     YYABORT;
  740.     }
  741.  
  742. #if YYDEBUG != 0
  743.   if (yydebug)
  744.     fprintf(stderr, "Entering state %d\n", yystate);
  745. #endif
  746.  
  747.  yybackup:
  748.  
  749. /* Do appropriate processing given the current state.  */
  750. /* Read a lookahead token if we need one and don't already have one.  */
  751. /* yyresume: */
  752.  
  753.   /* First try to decide what to do without reference to lookahead token.  */
  754.  
  755.   yyn = yypact[yystate];
  756.   if (yyn == YYFLAG)
  757.     goto yydefault;
  758.  
  759.   /* Not known => get a lookahead token if don't already have one.  */
  760.  
  761.   /* yychar is either YYEMPTY or YYEOF
  762.      or a valid token in external form.  */
  763.  
  764.   if (yychar == YYEMPTY)
  765.     {
  766. #if YYDEBUG != 0
  767.       if (yydebug)
  768.     fprintf(stderr, "Reading a token: ");
  769. #endif
  770.       yychar = YYLEX;
  771.     }
  772.  
  773.   /* Convert token to internal form (in yychar1) for indexing tables with */
  774.  
  775.   if (yychar <= 0)        /* This means end of input. */
  776.     {
  777.       yychar1 = 0;
  778.       yychar = YYEOF;        /* Don't call YYLEX any more */
  779.  
  780. #if YYDEBUG != 0
  781.       if (yydebug)
  782.     fprintf(stderr, "Now at end of input.\n");
  783. #endif
  784.     }
  785.   else
  786.     {
  787.       yychar1 = YYTRANSLATE(yychar);
  788.  
  789. #if YYDEBUG != 0
  790.       if (yydebug)
  791.     fprintf(stderr, "Next token is %d (%s)\n", yychar, yytname[yychar1]);
  792. #endif
  793.     }
  794.  
  795.   yyn += yychar1;
  796.   if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
  797.     goto yydefault;
  798.  
  799.   yyn = yytable[yyn];
  800.  
  801.   /* yyn is what to do for this token type in this state.
  802.      Negative => reduce, -yyn is rule number.
  803.      Positive => shift, yyn is new state.
  804.        New state is final state => don't bother to shift,
  805.        just return success.
  806.      0, or most negative number => error.  */
  807.  
  808.   if (yyn < 0)
  809.     {
  810.       if (yyn == YYFLAG)
  811.     goto yyerrlab;
  812.       yyn = -yyn;
  813.       goto yyreduce;
  814.     }
  815.   else if (yyn == 0)
  816.     goto yyerrlab;
  817.  
  818.   if (yyn == YYFINAL)
  819.     YYACCEPT;
  820.  
  821.   /* Shift the lookahead token.  */
  822.  
  823. #if YYDEBUG != 0
  824.   if (yydebug)
  825.     fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
  826. #endif
  827.  
  828.   /* Discard the token being shifted unless it is eof.  */
  829.   if (yychar != YYEOF)
  830.     yychar = YYEMPTY;
  831.  
  832.   *++yyvsp = yylval;
  833. #ifdef YYLSP_NEEDED
  834.   *++yylsp = yylloc;
  835. #endif
  836.  
  837.   /* count tokens shifted since error; after three, turn off error status.  */
  838.   if (yyerrstatus) yyerrstatus--;
  839.  
  840.   yystate = yyn;
  841.   goto yynewstate;
  842.  
  843. /* Do the default action for the current state.  */
  844. yydefault:
  845.  
  846.   yyn = yydefact[yystate];
  847.   if (yyn == 0)
  848.     goto yyerrlab;
  849.  
  850. /* Do a reduction.  yyn is the number of a rule to reduce with.  */
  851. yyreduce:
  852.   yylen = yyr2[yyn];
  853.   yyval = yyvsp[1-yylen]; /* implement default value of the action */
  854.  
  855. #if YYDEBUG != 0
  856.   if (yydebug)
  857.     {
  858.       int i;
  859.  
  860.       fprintf (stderr, "Reducing via rule %d (line %d), ",
  861.            yyn, yyrline[yyn]);
  862.  
  863.       /* Print the symboles being reduced, and their result.  */
  864.       for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
  865.     fprintf (stderr, "%s ", yytname[yyrhs[i]]);
  866.       fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
  867.     }
  868. #endif
  869.  
  870.  
  871.   switch (yyn) {
  872.  
  873. case 1:
  874. #line 115 "parse.y"
  875. {
  876.               /* Case of regular command.  Discard the error
  877.                  safety net,and return the command just parsed. */
  878.               global_command = yyvsp[-1].command;
  879.               eof_encountered = 0;
  880.               discard_parser_constructs (0);
  881.               YYACCEPT;
  882.             ;
  883.     break;}
  884. case 2:
  885. #line 124 "parse.y"
  886. {
  887.               /* Case of regular command, but not a very
  888.                  interesting one.  Return a NULL command. */
  889.               global_command = (COMMAND *)NULL;
  890.               YYACCEPT;
  891.             ;
  892.     break;}
  893. case 3:
  894. #line 132 "parse.y"
  895. {
  896.               /* Error during parsing.  Return NULL command. */
  897.               global_command = (COMMAND *)NULL;
  898.               eof_encountered = 0;
  899.               discard_parser_constructs (1);
  900.               if (interactive)
  901.                 {
  902.                   YYACCEPT;
  903.                 }
  904.               else
  905.                 {
  906.                   YYABORT;
  907.                 }
  908.             ;
  909.     break;}
  910. case 4:
  911. #line 147 "parse.y"
  912. {
  913.               /* Case of EOF seen by itself.  Do ignoreeof or 
  914.                  not. */
  915.               global_command = (COMMAND *)NULL;
  916.               handle_eof_input_unit ();
  917.               YYACCEPT;
  918.             ;
  919.     break;}
  920. case 5:
  921. #line 157 "parse.y"
  922. { yyval.word_list = (WORD_LIST *)NULL; ;
  923.     break;}
  924. case 6:
  925. #line 159 "parse.y"
  926. { yyval.word_list = make_word_list (yyvsp[0].word, yyvsp[-1].word_list); ;
  927.     break;}
  928. case 7:
  929. #line 163 "parse.y"
  930. { yyval.redirect = make_redirection ( 1, r_output_direction, yyvsp[0].word); ;
  931.     break;}
  932. case 8:
  933. #line 165 "parse.y"
  934. { yyval.redirect = make_redirection ( 0, r_input_direction, yyvsp[0].word); ;
  935.     break;}
  936. case 9:
  937. #line 167 "parse.y"
  938. { yyval.redirect = make_redirection (yyvsp[-2].number, r_output_direction, yyvsp[0].word); ;
  939.     break;}
  940. case 10:
  941. #line 169 "parse.y"
  942. { yyval.redirect = make_redirection (yyvsp[-2].number, r_input_direction, yyvsp[0].word); ;
  943.     break;}
  944. case 11:
  945. #line 171 "parse.y"
  946. { yyval.redirect = make_redirection ( 1, r_appending_to, yyvsp[0].word); ;
  947.     break;}
  948. case 12:
  949. #line 173 "parse.y"
  950. { yyval.redirect = make_redirection (yyvsp[-2].number, r_appending_to, yyvsp[0].word); ;
  951.     break;}
  952. case 13:
  953. #line 175 "parse.y"
  954. {
  955.               yyval.redirect = make_redirection ( 0, r_reading_until, yyvsp[0].word);
  956.               redirection_needing_here_doc = yyval.redirect;
  957.               need_here_doc = 1;
  958.             ;
  959.     break;}
  960. case 14:
  961. #line 181 "parse.y"
  962. {
  963.               yyval.redirect = make_redirection (yyvsp[-2].number, r_reading_until, yyvsp[0].word);
  964.               redirection_needing_here_doc = yyval.redirect;
  965.               need_here_doc = 1;
  966.             ;
  967.     break;}
  968. case 15:
  969. #line 187 "parse.y"
  970. {
  971.               yyval.redirect = make_redirection ( 0, r_duplicating_input, yyvsp[0].number);
  972.             ;
  973.     break;}
  974. case 16:
  975. #line 191 "parse.y"
  976. {
  977.               yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_input, yyvsp[0].number);
  978.             ;
  979.     break;}
  980. case 17:
  981. #line 195 "parse.y"
  982. {
  983.               yyval.redirect = make_redirection ( 1, r_duplicating_output, yyvsp[0].number);
  984.             ;
  985.     break;}
  986. case 18:
  987. #line 199 "parse.y"
  988. {
  989.               yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_output, yyvsp[0].number);
  990.             ;
  991.     break;}
  992. case 19:
  993. #line 203 "parse.y"
  994. {
  995.               yyval.redirect = make_redirection
  996.                 (0, r_duplicating_input_word, yyvsp[0].word);
  997.             ;
  998.     break;}
  999. case 20:
  1000. #line 208 "parse.y"
  1001. {
  1002.               yyval.redirect = make_redirection
  1003.                 (yyvsp[-2].number, r_duplicating_input_word, yyvsp[0].word);
  1004.             ;
  1005.     break;}
  1006. case 21:
  1007. #line 213 "parse.y"
  1008. {
  1009.               yyval.redirect = make_redirection
  1010.                 (1, r_duplicating_output_word, yyvsp[0].word);
  1011.             ;
  1012.     break;}
  1013. case 22:
  1014. #line 218 "parse.y"
  1015. {
  1016.               yyval.redirect = make_redirection
  1017.                 (yyvsp[-2].number, r_duplicating_output_word, yyvsp[0].word);
  1018.             ;
  1019.     break;}
  1020. case 23:
  1021. #line 223 "parse.y"
  1022. {
  1023.               yyval.redirect = make_redirection
  1024.                 (0, r_deblank_reading_until, yyvsp[0].word);
  1025.               redirection_needing_here_doc = yyval.redirect;
  1026.               need_here_doc = 1;
  1027.             ;
  1028.     break;}
  1029. case 24:
  1030. #line 230 "parse.y"
  1031. {
  1032.               yyval.redirect = make_redirection
  1033.                 (yyvsp[-2].number, r_deblank_reading_until, yyvsp[0].word);
  1034.               redirection_needing_here_doc = yyval.redirect;
  1035.               need_here_doc = 1;
  1036.             ;
  1037.     break;}
  1038. case 25:
  1039. #line 237 "parse.y"
  1040. { yyval.redirect = make_redirection ( 1, r_close_this, 0); ;
  1041.     break;}
  1042. case 26:
  1043. #line 239 "parse.y"
  1044. { yyval.redirect = make_redirection (yyvsp[-2].number, r_close_this, 0); ;
  1045.     break;}
  1046. case 27:
  1047. #line 241 "parse.y"
  1048. { yyval.redirect = make_redirection ( 0, r_close_this, 0); ;
  1049.     break;}
  1050. case 28:
  1051. #line 243 "parse.y"
  1052. { yyval.redirect = make_redirection (yyvsp[-2].number, r_close_this, 0); ;
  1053.     break;}
  1054. case 29:
  1055. #line 245 "parse.y"
  1056. { yyval.redirect = make_redirection ( 1, r_err_and_out, yyvsp[0].word); ;
  1057.     break;}
  1058. case 30:
  1059. #line 247 "parse.y"
  1060. { yyval.redirect = make_redirection ( yyvsp[-2].number, r_input_output, yyvsp[0].word); ;
  1061.     break;}
  1062. case 31:
  1063. #line 249 "parse.y"
  1064. {
  1065.               REDIRECT *t1, *t2;
  1066.               extern WORD_DESC *copy_word ();
  1067.  
  1068.               t1 = make_redirection ( 0, r_input_direction, yyvsp[0].word);
  1069.               t2 = make_redirection ( 1, r_output_direction, copy_word (yyvsp[0].word));
  1070.               t1->next = t2;
  1071.               yyval.redirect = t1;
  1072.             ;
  1073.     break;}
  1074. case 32:
  1075. #line 259 "parse.y"
  1076. { yyval.redirect = make_redirection ( 1, r_output_force, yyvsp[0].word); ;
  1077.     break;}
  1078. case 33:
  1079. #line 261 "parse.y"
  1080. { yyval.redirect = make_redirection ( yyvsp[-2].number, r_output_force, yyvsp[0].word); ;
  1081.     break;}
  1082. case 34:
  1083. #line 265 "parse.y"
  1084. { yyval.element.word = yyvsp[0].word; yyval.element.redirect = 0; ;
  1085.     break;}
  1086. case 35:
  1087. #line 267 "parse.y"
  1088. { yyval.element.redirect = yyvsp[0].redirect; yyval.element.word = 0; ;
  1089.     break;}
  1090. case 36:
  1091. #line 271 "parse.y"
  1092. {
  1093.               yyval.redirect = yyvsp[0].redirect;
  1094.             ;
  1095.     break;}
  1096. case 37:
  1097. #line 275 "parse.y"
  1098.               register REDIRECT *t = yyvsp[-1].redirect;
  1099.  
  1100.               while (t->next)
  1101.                 t = t->next;
  1102.               t->next = yyvsp[0].redirect; 
  1103.               yyval.redirect = yyvsp[-1].redirect;
  1104.             ;
  1105.     break;}
  1106. case 38:
  1107. #line 286 "parse.y"
  1108. { yyval.command = make_simple_command (yyvsp[0].element, (COMMAND *)NULL); ;
  1109.     break;}
  1110. case 39:
  1111. #line 288 "parse.y"
  1112. { yyval.command = make_simple_command (yyvsp[0].element, yyvsp[-1].command); ;
  1113.     break;}
  1114. case 40:
  1115. #line 292 "parse.y"
  1116. { yyval.command = clean_simple_command (yyvsp[0].command); ;
  1117.     break;}
  1118. case 41:
  1119. #line 294 "parse.y"
  1120. { yyval.command = yyvsp[0].command; ;
  1121.     break;}
  1122. case 42:
  1123. #line 298 "parse.y"
  1124. { yyval.command = yyvsp[0].command; ;
  1125.     break;}
  1126. case 43:
  1127. #line 300 "parse.y"
  1128. { yyvsp[-1].command->redirects = yyvsp[0].redirect; yyval.command = yyvsp[-1].command; ;
  1129.     break;}
  1130. case 44:
  1131. #line 303 "parse.y"
  1132. { yyvsp[0].command->redirects = yyvsp[-1].redirect; yyval.command = yyvsp[0].command; ;
  1133.     break;}
  1134. case 45:
  1135. #line 307 "parse.y"
  1136. { yyval.command = make_for_command (yyvsp[-4].word, (WORD_LIST *)add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
  1137.     break;}
  1138. case 46:
  1139. #line 309 "parse.y"
  1140. { yyval.command = make_for_command (yyvsp[-4].word, (WORD_LIST *)add_string_to_list ("$@", (WORD_LIST *)NULL), yyvsp[-1].command); ;
  1141.     break;}
  1142. case 47:
  1143. #line 311 "parse.y"
  1144. { yyval.command = make_for_command (yyvsp[-5].word, (WORD_LIST *)add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
  1145.     break;}
  1146. case 48:
  1147. #line 313 "parse.y"
  1148. { yyval.command = make_for_command (yyvsp[-5].word, (WORD_LIST *)add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
  1149.     break;}
  1150. case 49:
  1151. #line 316 "parse.y"
  1152. { yyval.command = make_for_command (yyvsp[-8].word, (WORD_LIST *)reverse_list (yyvsp[-5].word_list), yyvsp[-1].command); ;
  1153.     break;}
  1154. case 50:
  1155. #line 318 "parse.y"
  1156. { yyval.command = make_for_command (yyvsp[-8].word, (WORD_LIST *)reverse_list (yyvsp[-5].word_list), yyvsp[-1].command); ;
  1157.     break;}
  1158. case 51:
  1159. #line 321 "parse.y"
  1160. { yyval.command = make_case_command (yyvsp[-4].word, (PATTERN_LIST *)NULL); ;
  1161.     break;}
  1162. case 52:
  1163. #line 323 "parse.y"
  1164. { yyval.command = make_case_command (yyvsp[-5].word, yyvsp[-2].pattern); ;
  1165.     break;}
  1166. case 53:
  1167. #line 325 "parse.y"
  1168. { /* Nobody likes this...
  1169.                  report_syntax_error ("Inserted `;;'"); */
  1170.               yyval.command = make_case_command (yyvsp[-4].word, yyvsp[-1].pattern); ;
  1171.     break;}
  1172. case 54:
  1173. #line 330 "parse.y"
  1174. { yyval.command = yyvsp[0].command; ;
  1175.     break;}
  1176. case 55:
  1177. #line 332 "parse.y"
  1178. { yyval.command = make_while_command (yyvsp[-3].command, yyvsp[-1].command); ;
  1179.     break;}
  1180. case 56:
  1181. #line 334 "parse.y"
  1182. { yyval.command = make_until_command (yyvsp[-3].command, yyvsp[-1].command); ;
  1183.     break;}
  1184. case 57:
  1185. #line 337 "parse.y"
  1186. { yyvsp[-1].command->flags |= CMD_WANT_SUBSHELL; yyval.command = yyvsp[-1].command; ;
  1187.     break;}
  1188. case 58:
  1189. #line 340 "parse.y"
  1190. { yyval.command = yyvsp[0].command; ;
  1191.     break;}
  1192. case 59:
  1193. #line 343 "parse.y"
  1194. { yyval.command = make_function_def (yyvsp[-4].word, yyvsp[0].command); ;
  1195.     break;}
  1196. case 60:
  1197. #line 346 "parse.y"
  1198. { yyval.command = make_function_def (yyvsp[-4].word, yyvsp[0].command); ;
  1199.     break;}
  1200. case 61:
  1201. #line 349 "parse.y"
  1202. { yyval.command = make_function_def (yyvsp[-2].word, yyvsp[0].command); ;
  1203.     break;}
  1204. case 62:
  1205. #line 353 "parse.y"
  1206. { yyval.command = make_if_command (yyvsp[-3].command, yyvsp[-1].command, (COMMAND *)NULL); ;
  1207.     break;}
  1208. case 63:
  1209. #line 355 "parse.y"
  1210. { yyval.command = make_if_command (yyvsp[-5].command, yyvsp[-3].command, yyvsp[-1].command); ;
  1211.     break;}
  1212. case 64:
  1213. #line 357 "parse.y"
  1214. { yyval.command = make_if_command (yyvsp[-4].command, yyvsp[-2].command, yyvsp[-1].command); ;
  1215.     break;}
  1216. case 65:
  1217. #line 362 "parse.y"
  1218. { yyval.command = make_group_command (yyvsp[-1].command); ;
  1219.     break;}
  1220. case 66:
  1221. #line 366 "parse.y"
  1222. { yyval.command = make_if_command (yyvsp[-2].command, yyvsp[0].command, (COMMAND *)NULL); ;
  1223.     break;}
  1224. case 67:
  1225. #line 368 "parse.y"
  1226. { yyval.command = make_if_command (yyvsp[-4].command, yyvsp[-2].command, yyvsp[0].command); ;
  1227.     break;}
  1228. case 68:
  1229. #line 370 "parse.y"
  1230. { yyval.command = make_if_command (yyvsp[-3].command, yyvsp[-1].command, yyvsp[0].command); ;
  1231.     break;}
  1232. case 70:
  1233. #line 375 "parse.y"
  1234. { yyvsp[0].pattern->next = yyvsp[-1].pattern; yyval.pattern = yyvsp[0].pattern; ;
  1235.     break;}
  1236. case 71:
  1237. #line 379 "parse.y"
  1238. { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, yyvsp[0].command); ;
  1239.     break;}
  1240. case 72:
  1241. #line 381 "parse.y"
  1242. { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, (COMMAND *)NULL); ;
  1243.     break;}
  1244. case 73:
  1245. #line 383 "parse.y"
  1246. { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, yyvsp[0].command); ;
  1247.     break;}
  1248. case 74:
  1249. #line 385 "parse.y"
  1250. { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, (COMMAND *)NULL); ;
  1251.     break;}
  1252. case 76:
  1253. #line 391 "parse.y"
  1254. { yyvsp[0].pattern->next = yyvsp[-1].pattern; yyval.pattern = yyvsp[0].pattern; ;
  1255.     break;}
  1256. case 77:
  1257. #line 395 "parse.y"
  1258. { yyval.pattern = make_pattern_list (yyvsp[-3].word_list, yyvsp[-1].command); ;
  1259.     break;}
  1260. case 78:
  1261. #line 397 "parse.y"
  1262. { yyval.pattern = make_pattern_list (yyvsp[-3].word_list, (COMMAND *)NULL); ;
  1263.     break;}
  1264. case 79:
  1265. #line 399 "parse.y"
  1266. { yyval.pattern = make_pattern_list (yyvsp[-3].word_list, yyvsp[-1].command); ;
  1267.     break;}
  1268. case 80:
  1269. #line 401 "parse.y"
  1270. { yyval.pattern = make_pattern_list (yyvsp[-3].word_list, (COMMAND *)NULL); ;
  1271.     break;}
  1272. case 81:
  1273. #line 405 "parse.y"
  1274. { yyval.word_list = make_word_list (yyvsp[0].word, (WORD_LIST *)NULL); ;
  1275.     break;}
  1276. case 82:
  1277. #line 407 "parse.y"
  1278. { yyval.word_list = make_word_list (yyvsp[0].word, yyvsp[-2].word_list); ;
  1279.     break;}
  1280. case 83:
  1281. #line 416 "parse.y"
  1282. {
  1283.               yyval.command = yyvsp[0].command;
  1284.               if (need_here_doc)
  1285.                 make_here_document (redirection_needing_here_doc);
  1286.               need_here_doc = 0;
  1287.              ;
  1288.     break;}
  1289. case 86:
  1290. #line 427 "parse.y"
  1291. { yyval.command = command_connect (yyvsp[-2].command, 0, '&'); ;
  1292.     break;}
  1293. case 88:
  1294. #line 433 "parse.y"
  1295. { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, AND_AND); ;
  1296.     break;}
  1297. case 89:
  1298. #line 435 "parse.y"
  1299. { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, OR_OR); ;
  1300.     break;}
  1301. case 90:
  1302. #line 437 "parse.y"
  1303. { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, '&'); ;
  1304.     break;}
  1305. case 91:
  1306. #line 439 "parse.y"
  1307. { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, ';'); ;
  1308.     break;}
  1309. case 92:
  1310. #line 441 "parse.y"
  1311. { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, ';'); ;
  1312.     break;}
  1313. case 93:
  1314. #line 443 "parse.y"
  1315. { yyval.command = yyvsp[0].command; ;
  1316.     break;}
  1317. case 94:
  1318. #line 445 "parse.y"
  1319. {
  1320.               yyvsp[0].command->flags |= CMD_INVERT_RETURN;
  1321.               yyval.command = yyvsp[0].command;
  1322.             ;
  1323.     break;}
  1324. case 100:
  1325. #line 467 "parse.y"
  1326. {
  1327.               yyval.command = yyvsp[0].command;
  1328.               if (need_here_doc)
  1329.                 make_here_document (redirection_needing_here_doc);
  1330.               need_here_doc = 0;
  1331.             ;
  1332.     break;}
  1333. case 101:
  1334. #line 474 "parse.y"
  1335. {
  1336.               yyval.command = command_connect (yyvsp[-1].command, (COMMAND *)NULL, '&');
  1337.               if (need_here_doc)
  1338.                 make_here_document (redirection_needing_here_doc);
  1339.               need_here_doc = 0;
  1340.             ;
  1341.     break;}
  1342. case 102:
  1343. #line 481 "parse.y"
  1344. {
  1345.               yyval.command = yyvsp[-1].command;
  1346.               if (need_here_doc)
  1347.                 make_here_document (redirection_needing_here_doc);
  1348.               need_here_doc = 0;
  1349.             ;
  1350.     break;}
  1351. case 103:
  1352. #line 490 "parse.y"
  1353. { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, AND_AND); ;
  1354.     break;}
  1355. case 104:
  1356. #line 492 "parse.y"
  1357. { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, OR_OR); ;
  1358.     break;}
  1359. case 105:
  1360. #line 494 "parse.y"
  1361. { yyval.command = command_connect (yyvsp[-2].command, yyvsp[0].command, '&'); ;
  1362.     break;}
  1363. case 106:
  1364. #line 496 "parse.y"
  1365. { yyval.command = command_connect (yyvsp[-2].command, yyvsp[0].command, ';'); ;
  1366.     break;}
  1367. case 107:
  1368. #line 498 "parse.y"
  1369. { yyval.command = yyvsp[0].command; ;
  1370.     break;}
  1371. case 108:
  1372. #line 500 "parse.y"
  1373. {
  1374.               yyvsp[0].command->flags |= CMD_INVERT_RETURN;
  1375.               yyval.command = yyvsp[0].command;
  1376.             ;
  1377.     break;}
  1378. case 109:
  1379. #line 508 "parse.y"
  1380. { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, '|'); ;
  1381.     break;}
  1382. case 110:
  1383. #line 510 "parse.y"
  1384. { yyval.command = yyvsp[0].command; ;
  1385.     break;}
  1386. }
  1387.    /* the action file gets copied in in place of this dollarsign */
  1388. #line 423 "/usr/gnu/lib/bison.simple"
  1389.  
  1390.   yyvsp -= yylen;
  1391.   yyssp -= yylen;
  1392. #ifdef YYLSP_NEEDED
  1393.   yylsp -= yylen;
  1394. #endif
  1395.  
  1396. #if YYDEBUG != 0
  1397.   if (yydebug)
  1398.     {
  1399.       short *ssp1 = yyss - 1;
  1400.       fprintf (stderr, "state stack now");
  1401.       while (ssp1 != yyssp)
  1402.     fprintf (stderr, " %d", *++ssp1);
  1403.       fprintf (stderr, "\n");
  1404.     }
  1405. #endif
  1406.  
  1407.   *++yyvsp = yyval;
  1408.  
  1409. #ifdef YYLSP_NEEDED
  1410.   yylsp++;
  1411.   if (yylen == 0)
  1412.     {
  1413.       yylsp->first_line = yylloc.first_line;
  1414.       yylsp->first_column = yylloc.first_column;
  1415.       yylsp->last_line = (yylsp-1)->last_line;
  1416.       yylsp->last_column = (yylsp-1)->last_column;
  1417.       yylsp->text = 0;
  1418.     }
  1419.   else
  1420.     {
  1421.       yylsp->last_line = (yylsp+yylen-1)->last_line;
  1422.       yylsp->last_column = (yylsp+yylen-1)->last_column;
  1423.     }
  1424. #endif
  1425.  
  1426.   /* Now "shift" the result of the reduction.
  1427.      Determine what state that goes to,
  1428.      based on the state we popped back to
  1429.      and the rule number reduced by.  */
  1430.  
  1431.   yyn = yyr1[yyn];
  1432.  
  1433.   yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
  1434.   if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
  1435.     yystate = yytable[yystate];
  1436.   else
  1437.     yystate = yydefgoto[yyn - YYNTBASE];
  1438.  
  1439.   goto yynewstate;
  1440.  
  1441. yyerrlab:   /* here on detecting error */
  1442.  
  1443.   if (! yyerrstatus)
  1444.     /* If not already recovering from an error, report this error.  */
  1445.     {
  1446.       ++yynerrs;
  1447.  
  1448. #ifdef YYERROR_VERBOSE
  1449.       yyn = yypact[yystate];
  1450.  
  1451.       if (yyn > YYFLAG && yyn < YYLAST)
  1452.     {
  1453.       int size = 0;
  1454.       char *msg;
  1455.       int x, count;
  1456.  
  1457.       count = 0;
  1458.       for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
  1459.         if (yycheck[x + yyn] == x)
  1460.           size += strlen(yytname[x]) + 15, count++;
  1461.       msg = (char *) xmalloc(size + 15);
  1462.       strcpy(msg, "parse error");
  1463.  
  1464.       if (count < 5)
  1465.         {
  1466.           count = 0;
  1467.           for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
  1468.         if (yycheck[x + yyn] == x)
  1469.           {
  1470.             strcat(msg, count == 0 ? ", expecting `" : " or `");
  1471.             strcat(msg, yytname[x]);
  1472.             strcat(msg, "'");
  1473.             count++;
  1474.           }
  1475.         }
  1476.       yyerror(msg);
  1477.       free(msg);
  1478.     }
  1479.       else
  1480. #endif /* YYERROR_VERBOSE */
  1481.     yyerror("parse error");
  1482.     }
  1483.  
  1484. yyerrlab1:   /* here on error raised explicitly by an action */
  1485.  
  1486.   if (yyerrstatus == 3)
  1487.     {
  1488.       /* if just tried and failed to reuse lookahead token after an error, discard it.  */
  1489.  
  1490.       /* return failure if at end of input */
  1491.       if (yychar == YYEOF)
  1492.     YYABORT;
  1493.  
  1494. #if YYDEBUG != 0
  1495.       if (yydebug)
  1496.     fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
  1497. #endif
  1498.  
  1499.       yychar = YYEMPTY;
  1500.     }
  1501.  
  1502.   /* Else will try to reuse lookahead token
  1503.      after shifting the error token.  */
  1504.  
  1505.   yyerrstatus = 3;        /* Each real token shifted decrements this */
  1506.  
  1507.   goto yyerrhandle;
  1508.  
  1509. yyerrdefault:  /* current state does not do anything special for the error token. */
  1510.  
  1511. #if 0
  1512.   /* This is wrong; only states that explicitly want error tokens
  1513.      should shift them.  */
  1514.   yyn = yydefact[yystate];  /* If its default is to accept any token, ok.  Otherwise pop it.*/
  1515.   if (yyn) goto yydefault;
  1516. #endif
  1517.  
  1518. yyerrpop:   /* pop the current state because it cannot handle the error token */
  1519.  
  1520.   if (yyssp == yyss) YYABORT;
  1521.   yyvsp--;
  1522.   yystate = *--yyssp;
  1523. #ifdef YYLSP_NEEDED
  1524.   yylsp--;
  1525. #endif
  1526.  
  1527. #if YYDEBUG != 0
  1528.   if (yydebug)
  1529.     {
  1530.       short *ssp1 = yyss - 1;
  1531.       fprintf (stderr, "Error: state stack now");
  1532.       while (ssp1 != yyssp)
  1533.     fprintf (stderr, " %d", *++ssp1);
  1534.       fprintf (stderr, "\n");
  1535.     }
  1536. #endif
  1537.  
  1538. yyerrhandle:
  1539.  
  1540.   yyn = yypact[yystate];
  1541.   if (yyn == YYFLAG)
  1542.     goto yyerrdefault;
  1543.  
  1544.   yyn += YYTERROR;
  1545.   if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
  1546.     goto yyerrdefault;
  1547.  
  1548.   yyn = yytable[yyn];
  1549.   if (yyn < 0)
  1550.     {
  1551.       if (yyn == YYFLAG)
  1552.     goto yyerrpop;
  1553.       yyn = -yyn;
  1554.       goto yyreduce;
  1555.     }
  1556.   else if (yyn == 0)
  1557.     goto yyerrpop;
  1558.  
  1559.   if (yyn == YYFINAL)
  1560.     YYACCEPT;
  1561.  
  1562. #if YYDEBUG != 0
  1563.   if (yydebug)
  1564.     fprintf(stderr, "Shifting error token, ");
  1565. #endif
  1566.  
  1567.   *++yyvsp = yylval;
  1568. #ifdef YYLSP_NEEDED
  1569.   *++yylsp = yylloc;
  1570. #endif
  1571.  
  1572.   yystate = yyn;
  1573.   goto yynewstate;
  1574. }
  1575. #line 512 "parse.y"
  1576.  
  1577.  
  1578. /* Initial size to allocate for tokens, and the
  1579.    amount to grow them by. */
  1580. #define TOKEN_DEFAULT_GROW_SIZE 512
  1581.  
  1582. /* The token currently being read. */
  1583. int current_token = 0;
  1584.  
  1585. /* The last read token, or NULL.  read_token () uses this for context
  1586.    checking. */
  1587. int last_read_token = 0;
  1588.  
  1589. /* The token read prior to last_read_token. */
  1590. int token_before_that = 0;
  1591.  
  1592. /* Global var is non-zero when end of file has been reached. */
  1593. int EOF_Reached = 0;
  1594.  
  1595. /* yy_getc () returns the next available character from input or EOF.
  1596.    yy_ungetc (c) makes `c' the next character to read.
  1597.    init_yy_io (get, unget, type, location) makes the function GET the
  1598.    installed function for getting the next character, makes UNGET the
  1599.    installed function for un-getting a character, set the type of stream
  1600.    (either string or file) from TYPE, and makes LOCATION point to where
  1601.    the input is coming from. */
  1602.  
  1603. /* Unconditionally returns end-of-file. */
  1604. return_EOF ()
  1605. {
  1606.   return (EOF);
  1607. }
  1608.  
  1609. /* Variable containing the current get and unget functions.
  1610.    See ./input.h for a clearer description. */
  1611. BASH_INPUT bash_input;
  1612.  
  1613. /* Set all of the fields in BASH_INPUT to NULL. */
  1614. void
  1615. initialize_bash_input ()
  1616. {
  1617.   bash_input.type = 0;
  1618.   bash_input.name = (char *)NULL;
  1619.   bash_input.location.file = (FILE *)NULL;
  1620.   bash_input.location.string = (char *)NULL;
  1621.   bash_input.getter = (Function *)NULL;
  1622.   bash_input.ungetter = (Function *)NULL;
  1623. }
  1624.  
  1625. /* Set the contents of the current bash input stream from
  1626.    GET, UNGET, TYPE, NAME, and LOCATION. */
  1627. init_yy_io (get, unget, type, name, location)
  1628.      Function *get, *unget;
  1629.      int type;
  1630.      char *name;
  1631.      INPUT_STREAM location;
  1632. {
  1633.   bash_input.type = type;
  1634.   if (bash_input.name)
  1635.     free (bash_input.name);
  1636.  
  1637.   if (name != (char *)NULL)
  1638.     bash_input.name = savestring (name);
  1639.   else
  1640.     bash_input.name = (char *)NULL;
  1641.  
  1642.   bash_input.location = location;
  1643.   bash_input.getter = get;
  1644.   bash_input.ungetter = unget;
  1645. }
  1646.  
  1647. /* Call this to get the next character of input. */
  1648. yy_getc ()
  1649. {
  1650.   return (*(bash_input.getter)) ();
  1651. }
  1652.  
  1653. /* Call this to unget C.  That is, to make C the next character
  1654.    to be read. */
  1655. yy_ungetc (c)
  1656. {
  1657.   return (*(bash_input.ungetter)) (c);
  1658. }
  1659.  
  1660. /* **************************************************************** */
  1661. /*                                    */
  1662. /*          Let input be read from readline ().            */
  1663. /*                                    */
  1664. /* **************************************************************** */
  1665.  
  1666. #if defined (READLINE)
  1667. char *current_readline_prompt = (char *)NULL;
  1668. char *current_readline_line = (char *)NULL;
  1669. int current_readline_line_index = 0;
  1670.  
  1671. static int readline_initialized_yet = 0;
  1672. int
  1673. yy_readline_get ()
  1674. {
  1675.   if (!current_readline_line)
  1676.     {
  1677.       extern sighandler sigint_sighandler ();
  1678.       extern int interrupt_immediately;
  1679.       extern char *readline ();
  1680.       SigHandler *old_sigint;
  1681. #if defined (JOB_CONTROL)
  1682.       extern pid_t shell_pgrp;
  1683.       extern int job_control;
  1684. #endif /* JOB_CONTROL */
  1685.  
  1686.       if (!readline_initialized_yet)
  1687.     {
  1688.       initialize_readline ();
  1689.       readline_initialized_yet = 1;
  1690.     }
  1691.  
  1692. #if defined (JOB_CONTROL)
  1693.       if (job_control)
  1694.     give_terminal_to (shell_pgrp);
  1695. #endif /* JOB_CONTROL */
  1696.  
  1697.       old_sigint = (SigHandler *)signal (SIGINT, sigint_sighandler);
  1698.       interrupt_immediately++;
  1699.  
  1700.       if (!current_readline_prompt)
  1701.     current_readline_line = readline ("");
  1702.       else
  1703.     current_readline_line = readline (current_readline_prompt);
  1704.  
  1705.       interrupt_immediately--;
  1706.       signal (SIGINT, old_sigint);
  1707.  
  1708.       /* Reset the prompt to whatever is in the decoded value of
  1709.      prompt_string_pointer. */
  1710.       reset_readline_prompt ();
  1711.  
  1712.       current_readline_line_index = 0;
  1713.  
  1714.       if (!current_readline_line)
  1715.     {
  1716.       current_readline_line_index = 0;
  1717.       return (EOF);
  1718.     }
  1719.  
  1720.       current_readline_line =
  1721.     (char *)xrealloc (current_readline_line,
  1722.               2 + strlen (current_readline_line));
  1723.       strcat (current_readline_line, "\n");
  1724.     }
  1725.  
  1726.   if (!current_readline_line[current_readline_line_index])
  1727.     {
  1728.       free (current_readline_line);
  1729.       current_readline_line = (char *)NULL;
  1730.       return (yy_readline_get ());
  1731.     }
  1732.   else
  1733.     {
  1734.       int c = current_readline_line[current_readline_line_index++];
  1735.       return (c);
  1736.     }
  1737. }
  1738.  
  1739. int
  1740. yy_readline_unget (c)
  1741. {
  1742.   if (current_readline_line_index && current_readline_line)
  1743.     current_readline_line[--current_readline_line_index] = c;
  1744.   return (c);
  1745. }
  1746.   
  1747. with_input_from_stdin ()
  1748. {
  1749.   INPUT_STREAM location;
  1750.  
  1751.   location.string = current_readline_line;
  1752.   init_yy_io (yy_readline_get, yy_readline_unget,
  1753.           st_string, "readline stdin", location);
  1754. }
  1755.  
  1756. #else  /* !READLINE */
  1757.  
  1758. with_input_from_stdin ()
  1759. {
  1760.   with_input_from_stream (stdin, "stdin");
  1761. }
  1762. #endif    /* !READLINE */
  1763.  
  1764. /* **************************************************************** */
  1765. /*                                    */
  1766. /*   Let input come from STRING.  STRING is zero terminated.        */
  1767. /*                                    */
  1768. /* **************************************************************** */
  1769.  
  1770. int
  1771. yy_string_get ()
  1772. {
  1773.   register char *string;
  1774.   register int c;
  1775.  
  1776.   string = bash_input.location.string;
  1777.   c = EOF;
  1778.  
  1779.   /* If the string doesn't exist, or is empty, EOF found. */
  1780.   if (string && *string)
  1781.     {
  1782.       c = *string++;
  1783.       bash_input.location.string = string;
  1784.     }
  1785.   return (c);
  1786. }
  1787.  
  1788. int
  1789. yy_string_unget (c)
  1790.      int c;
  1791. {
  1792.   *(--bash_input.location.string) = c;
  1793.   return (c);
  1794. }
  1795.  
  1796. void
  1797. with_input_from_string (string, name)
  1798.      char *string;
  1799.      char *name;
  1800. {
  1801.   INPUT_STREAM location;
  1802.  
  1803.   location.string = string;
  1804.  
  1805.   init_yy_io (yy_string_get, yy_string_unget, st_string, name, location);
  1806. }
  1807.  
  1808. /* **************************************************************** */
  1809. /*                                    */
  1810. /*             Let input come from STREAM.            */
  1811. /*                                    */
  1812. /* **************************************************************** */
  1813.  
  1814. int
  1815. yy_stream_get ()
  1816. {
  1817.   if (bash_input.location.file)
  1818. #if defined (USG) || (defined (_POSIX_VERSION) && defined (Ultrix))
  1819.     return (sysv_getc (bash_input.location.file));
  1820. #else
  1821.     return (getc (bash_input.location.file));
  1822. #endif    /* !USG && !(_POSIX_VERSION && Ultrix) */
  1823.   else
  1824.     return (EOF);
  1825. }
  1826.  
  1827. int
  1828. yy_stream_unget (c)
  1829.      int c;
  1830. {
  1831.   return (ungetc (c, bash_input.location.file));
  1832. }
  1833.  
  1834. with_input_from_stream (stream, name)
  1835.      FILE *stream;
  1836.      char *name;
  1837. {
  1838.   INPUT_STREAM location;
  1839.  
  1840.   location.file = stream;
  1841.   init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location);
  1842. }
  1843.  
  1844. typedef struct stream_saver {
  1845.   struct stream_saver *next;
  1846.   BASH_INPUT bash_input;
  1847.   int line;
  1848. } STREAM_SAVER;
  1849.  
  1850. /* The globally known line number. */
  1851. int line_number = 0;
  1852.  
  1853. STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
  1854.  
  1855. push_stream ()
  1856. {
  1857.   STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
  1858.  
  1859.   bcopy (&bash_input, &(saver->bash_input), sizeof (BASH_INPUT));
  1860.   saver->line = line_number;
  1861.   bash_input.name = (char *)NULL;
  1862.   saver->next = stream_list;
  1863.   stream_list = saver;
  1864.   EOF_Reached = line_number = 0;
  1865. }
  1866.  
  1867. pop_stream ()
  1868. {
  1869.   if (!stream_list)
  1870.     {
  1871.       EOF_Reached = 1;
  1872.     }
  1873.   else
  1874.     {
  1875.       STREAM_SAVER *saver = stream_list;
  1876.  
  1877.       EOF_Reached = 0;
  1878.       stream_list = stream_list->next;
  1879.  
  1880.       init_yy_io (saver->bash_input.getter,
  1881.           saver->bash_input.ungetter,
  1882.           saver->bash_input.type,
  1883.           saver->bash_input.name,
  1884.           saver->bash_input.location);
  1885.  
  1886.       line_number = saver->line;
  1887.  
  1888.       if (saver->bash_input.name)
  1889.     free (saver->bash_input.name);
  1890.  
  1891.       free (saver);
  1892.     }
  1893. }
  1894.  
  1895. /*
  1896.  * This is used to inhibit alias expansion and reserved word recognition
  1897.  * inside case statement pattern lists.  A `case statement pattern list'
  1898.  * is:
  1899.  *    everything between the `in' in a `case word in' and the next ')'
  1900.  *    or `esac'
  1901.  *    everything between a `;;' and the next `)' or `esac'
  1902.  */
  1903. static int in_case_pattern_list = 0;
  1904.  
  1905. #if defined (ALIAS)
  1906. /*
  1907.  * Pseudo-global variables used in implementing token-wise alias expansion.
  1908.  */
  1909.  
  1910. static int expand_next_token = 0;
  1911. static char *current_token_being_expanded = (char *)NULL;
  1912. static char *pending_token_being_expanded = (char *)NULL;
  1913.  
  1914. /*
  1915.  * Pushing and popping strings.  This works together with shell_getc to 
  1916.  * implement alias expansion on a per-token basis.
  1917.  */
  1918.  
  1919. typedef struct string_saver {
  1920.   struct string_saver *next;
  1921.   int expand_alias;  /* Value to set expand_alias to when string is popped. */
  1922.   char *saved_line;
  1923.   int saved_line_size, saved_line_index, saved_line_terminator;
  1924.   char *saved_token_being_expanded;
  1925. } STRING_SAVER;
  1926.  
  1927. STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL;
  1928.  
  1929. static void save_expansion ();
  1930.  
  1931. /*
  1932.  * Push the current shell_input_line onto a stack of such lines and make S
  1933.  * the current input.  Used when expanding aliases.  EXPAND is used to set
  1934.  * the value of expand_next_token when the string is popped, so that the
  1935.  * word after the alias in the original line is handled correctly when the
  1936.  * alias expands to multiple words.  TOKEN is the token that was expanded
  1937.  * into S; it is saved and used to prevent infinite recursive expansion.
  1938.  */
  1939. static void
  1940. push_string (s, expand, token)
  1941.      char *s;
  1942.      int expand;
  1943.      char *token;
  1944. {
  1945.   extern char *shell_input_line;
  1946.   extern int shell_input_line_size, shell_input_line_index,
  1947.          shell_input_line_terminator;
  1948.   STRING_SAVER *temp = (STRING_SAVER *) xmalloc (sizeof (STRING_SAVER));
  1949.  
  1950.   temp->expand_alias = expand;
  1951.   temp->saved_line = shell_input_line;
  1952.   temp->saved_line_size = shell_input_line_size;
  1953.   temp->saved_line_index = shell_input_line_index;
  1954.   temp->saved_line_terminator = shell_input_line_terminator;
  1955.   temp->saved_token_being_expanded = current_token_being_expanded;
  1956.   temp->next = pushed_string_list;
  1957.   pushed_string_list = temp;
  1958.  
  1959.   save_expansion (token);
  1960.  
  1961.   current_token_being_expanded = token;
  1962.   shell_input_line = s;
  1963.   shell_input_line_size = strlen (s);
  1964.   shell_input_line_index = 0;
  1965.   shell_input_line_terminator = '\0';
  1966.   expand_next_token = 0;
  1967. }
  1968.  
  1969. /*
  1970.  * Make the top of the pushed_string stack be the current shell input.
  1971.  * Only called when there is something on the stack.  Called from shell_getc
  1972.  * when it thinks it has consumed the string generated by an alias expansion
  1973.  * and needs to return to the original input line.
  1974.  */
  1975. static void
  1976. pop_string ()
  1977. {
  1978.   extern char *shell_input_line;
  1979.   extern int shell_input_line_size, shell_input_line_index,
  1980.          shell_input_line_terminator;
  1981.   STRING_SAVER *t;
  1982.  
  1983.   if (shell_input_line)
  1984.     free (shell_input_line);
  1985.   shell_input_line = pushed_string_list->saved_line;
  1986.   shell_input_line_index = pushed_string_list->saved_line_index;
  1987.   shell_input_line_size = pushed_string_list->saved_line_size;
  1988.   shell_input_line_terminator = pushed_string_list->saved_line_terminator;
  1989.   expand_next_token = pushed_string_list->expand_alias;
  1990.   pending_token_being_expanded = pushed_string_list->saved_token_being_expanded;
  1991.   t = pushed_string_list;
  1992.   pushed_string_list = pushed_string_list->next;
  1993.   free((char *)t);
  1994. }
  1995.  
  1996. static void
  1997. free_string_list ()
  1998. {
  1999.   register STRING_SAVER *t = pushed_string_list, *t1;
  2000.  
  2001.   while (t)
  2002.     {
  2003.       t1 = t->next;
  2004.       if (t->saved_line)
  2005.     free (t->saved_line);
  2006.       if (t->saved_token_being_expanded)
  2007.     free (t->saved_token_being_expanded);
  2008.       free ((char *)t);
  2009.       t = t1;
  2010.     }
  2011.   pushed_string_list = (STRING_SAVER *)NULL;
  2012. }
  2013.  
  2014. /* This is a stack to save the values of all tokens for which alias
  2015.    expansion has been performed during the current call to read_token ().
  2016.    It is used to prevent alias expansion loops:
  2017.  
  2018.       alias foo=bar
  2019.       alias bar=baz
  2020.       alias baz=foo
  2021.  
  2022.    Ideally this would be taken care of by push and pop string, but because
  2023.    of when strings are popped the stack will not contain the correct
  2024.    strings to test against.  (The popping is done in shell_getc, so that when
  2025.    the current string is exhausted, shell_getc can simply pop that string off
  2026.    the stack, restore the previous string, and continue with the character
  2027.    following the token whose expansion was originally pushed on the stack.)
  2028.  
  2029.    What we really want is a record of all tokens that have been expanded for
  2030.    aliases during the `current' call to read_token().  This does that, at the
  2031.    cost of being somewhat special-purpose (OK, OK vile and unclean).  Brian,
  2032.    you had better rewrite this whole piece of garbage before the next version
  2033.    is released.
  2034. */
  2035.  
  2036. typedef struct _exp_saver {
  2037.       struct _exp_saver *next;
  2038.       char *saved_token;
  2039. } EXPANSION_SAVER;
  2040.  
  2041. EXPANSION_SAVER *expanded_token_stack = (EXPANSION_SAVER *)NULL;
  2042.  
  2043. static void
  2044. save_expansion (s)
  2045.      char *s;
  2046. {
  2047.   EXPANSION_SAVER *t;
  2048.  
  2049.   t = (EXPANSION_SAVER *) xmalloc (sizeof (EXPANSION_SAVER));
  2050.   t->saved_token = savestring (s);
  2051.   t->next = expanded_token_stack;
  2052.   expanded_token_stack = t;
  2053. }
  2054.  
  2055. /*
  2056.  * Return 1 if TOKEN has already been expanded in the current `stack' of
  2057.  * expansions.  If it has been expanded already, it will appear as the value
  2058.  * of saved_token for some entry in the stack of expansions created for the
  2059.  * current token being expanded.
  2060.  */
  2061. static int
  2062. token_has_been_expanded (token)
  2063.      char *token;
  2064. {
  2065.   register EXPANSION_SAVER *t = expanded_token_stack;
  2066.  
  2067.   while (t)
  2068.     {
  2069.       if (STREQ (token, t->saved_token))
  2070.     return (1);
  2071.       t = t->next;
  2072.     }
  2073.   return (0);
  2074. }
  2075.  
  2076. static void
  2077. free_expansion_stack ()
  2078. {
  2079.   register EXPANSION_SAVER *t = expanded_token_stack, *t1;
  2080.  
  2081.   while (t)
  2082.     {
  2083.       t1 = t->next;
  2084.       free (t->saved_token);
  2085.       free (t);
  2086.       t = t1;
  2087.     }
  2088.   expanded_token_stack = (EXPANSION_SAVER *)NULL;
  2089. }
  2090.  
  2091. #endif /* ALIAS */
  2092.  
  2093. /* Return a line of text, taken from wherever yylex () reads input.
  2094.    If there is no more input, then we return NULL. */
  2095. char *
  2096. read_a_line ()
  2097. {
  2098.   char *line_buffer = (char *)NULL;
  2099.   int indx = 0, buffer_size = 0;
  2100.   int c;
  2101.  
  2102.   while (1)
  2103.     {
  2104.       c = yy_getc ();
  2105.  
  2106.       if (c == 0)
  2107.     continue;
  2108.  
  2109.       /* If there is no more input, then we return NULL. */
  2110.       if (c == EOF)
  2111.     {
  2112.       c = '\n';
  2113.       if (!line_buffer)
  2114.         return ((char *)NULL);
  2115.     }
  2116.  
  2117.       /* `+2' in case the final (200'th) character in the buffer is a newline;
  2118.      otherwise the code below that NULL-terminates it will write over the
  2119.      201st slot and kill the range checking in free(). */
  2120.       if (indx + 2 > buffer_size)
  2121.     if (!buffer_size)
  2122.       line_buffer = (char *)xmalloc (buffer_size = 200);
  2123.     else
  2124.       line_buffer = (char *)xrealloc (line_buffer, buffer_size += 200);
  2125.  
  2126.       line_buffer[indx++] = c;
  2127.       if (c == '\n')
  2128.     {
  2129.       line_buffer[indx] = '\0';
  2130.       return (line_buffer);
  2131.     }
  2132.     }
  2133. }
  2134.  
  2135. /* Return a line as in read_a_line (), but insure that the prompt is
  2136.    the secondary prompt. */
  2137. char *
  2138. read_secondary_line ()
  2139. {
  2140.   prompt_string_pointer = &ps2_prompt;
  2141.   prompt_again ();
  2142.   return (read_a_line ());
  2143. }
  2144.  
  2145.  
  2146. /* **************************************************************** */
  2147. /*                                    */
  2148. /*                YYLEX ()                */
  2149. /*                                    */
  2150. /* **************************************************************** */
  2151.  
  2152. /* Reserved words.  These are only recognized as the first word of a
  2153.    command.  TOKEN_WORD_ALIST. */
  2154. STRING_INT_ALIST word_token_alist[] = {
  2155.   { "if", IF },
  2156.   { "then", THEN },
  2157.   { "else", ELSE },
  2158.   { "elif", ELIF },
  2159.   { "fi", FI },
  2160.   { "case", CASE },
  2161.   { "esac", ESAC },
  2162.   { "for", FOR },
  2163.   { "while", WHILE },
  2164.   { "until", UNTIL },
  2165.   { "do", DO },
  2166.   { "done", DONE },
  2167.   { "in", IN },
  2168.   { "function", FUNCTION },
  2169.   { "{", '{' },
  2170.   { "}", '}' },
  2171.   { "!", BANG },
  2172.   { (char *)NULL,  0}
  2173. };
  2174.  
  2175. /* Where shell input comes from.  History expansion is performed on each
  2176.    line when the shell is interactive. */
  2177. char *shell_input_line = (char *)NULL;
  2178. int shell_input_line_index = 0;
  2179. int shell_input_line_size = 0;    /* Amount allocated for shell_input_line. */
  2180. int shell_input_line_len = 0;    /* strlen (shell_input_line) */
  2181.  
  2182. /* Either zero, or EOF. */
  2183. int shell_input_line_terminator = 0;
  2184.  
  2185. /* Return the next shell input character.  This always reads characters
  2186.    from shell_input_line; when that line is exhausted, it is time to
  2187.    read the next line. */
  2188. int
  2189. shell_getc (remove_quoted_newline)
  2190.      int remove_quoted_newline;
  2191. {
  2192.   int c;
  2193.  
  2194.   QUIT;
  2195.  
  2196. #if defined (ALIAS)
  2197.   /* If shell_input_line[shell_input_line_index] == 0, but there is
  2198.      something on the pushed list of strings, then we don't want to go
  2199.      off and get another line.  We let the code down below handle it. */
  2200.  
  2201.   if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
  2202.                 (pushed_string_list == (STRING_SAVER *)NULL)))
  2203. #else /* !ALIAS */
  2204.   if (!shell_input_line || !shell_input_line[shell_input_line_index])
  2205. #endif /* !ALIAS */
  2206.     {
  2207.       register int i, l;
  2208.       char *pre_process_line (), *expansions;
  2209.  
  2210.       restart_read_next_line:
  2211.  
  2212.       line_number++;
  2213.  
  2214.     restart_read:
  2215.  
  2216.       QUIT;    /* XXX experimental */
  2217.  
  2218.       i = 0;
  2219.       shell_input_line_terminator = 0;
  2220.  
  2221. #if defined (JOB_CONTROL)
  2222.       notify_and_cleanup ();
  2223. #endif
  2224.  
  2225.       clearerr (stdin);
  2226.       while (c = yy_getc ())
  2227.     {
  2228.       if (i + 2 > shell_input_line_size)
  2229.         shell_input_line = (char *)
  2230.           xrealloc (shell_input_line, shell_input_line_size += 256);
  2231.  
  2232.       if (c == EOF)
  2233.         {
  2234.           clearerr (stdin);
  2235.  
  2236.           if (!i)
  2237.         shell_input_line_terminator = EOF;
  2238.  
  2239.           shell_input_line[i] = '\0';
  2240.           break;
  2241.         }
  2242.  
  2243.       shell_input_line[i++] = c;
  2244.  
  2245.       if (c == '\n')
  2246.         {
  2247.           shell_input_line[--i] = '\0';
  2248.           current_command_line_count++;
  2249.           break;
  2250.         }
  2251.     }
  2252.       shell_input_line_index = 0;
  2253.       shell_input_line_len = i;        /* == strlen (shell_input_line) */
  2254.  
  2255.       if (!shell_input_line || !shell_input_line[0])
  2256.     goto after_pre_process;
  2257.  
  2258.       if (interactive)
  2259.     {
  2260.       expansions = pre_process_line (shell_input_line, 1, 1);
  2261.  
  2262.       free (shell_input_line);
  2263.       shell_input_line = expansions;
  2264.       shell_input_line_len = shell_input_line ?
  2265.                  strlen (shell_input_line) :
  2266.                  0;
  2267.       /* We have to force the xrealloc below because we don't know the
  2268.          true allocated size of shell_input_line anymore. */
  2269.       shell_input_line_size = shell_input_line_len;
  2270.     }
  2271.  
  2272.   after_pre_process:
  2273.       if (shell_input_line)
  2274.     {
  2275.       if (echo_input_at_read)
  2276.         fprintf (stderr, "%s\n", shell_input_line);
  2277.     }
  2278.       else
  2279.     {
  2280.       shell_input_line_size = 0;
  2281.       prompt_string_pointer = ¤t_prompt_string;
  2282.       prompt_again ();
  2283.       goto restart_read;
  2284.     }
  2285.  
  2286.       /* Add the newline to the end of this string, iff the string does
  2287.      not already end in an EOF character.  */
  2288.       if (shell_input_line_terminator != EOF)
  2289.     {
  2290.       l = shell_input_line_len;    /* was a call to strlen */
  2291.  
  2292.       if (l + 3 > shell_input_line_size)
  2293.         shell_input_line = (char *)xrealloc (shell_input_line,
  2294.                     1 + (shell_input_line_size += 2));
  2295.  
  2296.       strcpy (shell_input_line + l, "\n");
  2297.     }
  2298.     }
  2299.   
  2300.   c = shell_input_line[shell_input_line_index];
  2301.  
  2302.   if (c)
  2303.     shell_input_line_index++;
  2304.  
  2305.   if (c == '\\' && remove_quoted_newline &&
  2306.       shell_input_line[shell_input_line_index] == '\n')
  2307.     {
  2308.     prompt_again ();
  2309.     goto restart_read_next_line;
  2310.     }
  2311.  
  2312. #if defined (ALIAS)
  2313.   /*
  2314.    * If c is NULL, we have reached the end of the current input string.  If
  2315.    * pushed_string_list is non-empty, it's time to pop to the previous string
  2316.    * because we have fully consumed the result of the last alias expansion.
  2317.    * Do it transparently; just return the next character of the string popped
  2318.    * to.  We need to hang onto current_token_being_expanded until the token
  2319.    * currently being read has been recognized; we can't restore it in
  2320.    * pop_string () because the token currently being read would be
  2321.    * inappropriately compared with it.  We defer restoration until the next
  2322.    * call to read_token ().
  2323.    */
  2324.  
  2325.   if (!c && (pushed_string_list != (STRING_SAVER *)NULL))
  2326.     {
  2327.       pop_string ();
  2328.       c = shell_input_line[shell_input_line_index];
  2329.       if (c)
  2330.     shell_input_line_index++;
  2331.     }
  2332. #endif /* ALIAS */
  2333.  
  2334.   if (!c && shell_input_line_terminator == EOF)
  2335.     {
  2336.       if (shell_input_line_index != 0)
  2337.     return ('\n');
  2338.       else
  2339.     return (EOF);
  2340.     }
  2341.  
  2342.   return (c);
  2343. }
  2344.  
  2345. /* Put C back into the input for the shell. */
  2346. shell_ungetc (c)
  2347.      int c;
  2348. {
  2349.   if (shell_input_line && shell_input_line_index)
  2350.     shell_input_line[--shell_input_line_index] = c;
  2351. }
  2352.  
  2353. /* Discard input until CHARACTER is seen. */
  2354. discard_until (character)
  2355.      int character;
  2356. {
  2357.   int c;
  2358.  
  2359.   while ((c = shell_getc (0)) != EOF && c != character)
  2360.     ;
  2361.  
  2362.   if (c != EOF)
  2363.     shell_ungetc (c);
  2364. }
  2365.  
  2366. #if defined (HISTORY_REEDITING)
  2367. /* Tell readline () that we have some text for it to edit. */
  2368. re_edit (text)
  2369.      char *text;
  2370. {
  2371. #if defined (READLINE)
  2372.   if (strcmp (bash_input.name, "readline stdin") == 0)
  2373.     bash_re_edit (text);
  2374. #endif /* READLINE */
  2375. }
  2376. #endif /* HISTORY_REEDITING */
  2377.  
  2378. /* Non-zero means do no history expansion on this line, regardless
  2379.    of what history_expansion says. */
  2380. int history_expansion_inhibited = 0;
  2381.  
  2382. /* Do pre-processing on LINE.  If PRINT_CHANGES is non-zero, then
  2383.    print the results of expanding the line if there were any changes.
  2384.    If there is an error, return NULL, otherwise the expanded line is
  2385.    returned.  If ADDIT is non-zero the line is added to the history
  2386.    list after history expansion.  ADDIT is just a suggestion;
  2387.    REMEMBER_ON_HISTORY can veto, and does.
  2388.    Right now this does history expansion. */
  2389. char *
  2390. pre_process_line (line, print_changes, addit)
  2391.      char *line;
  2392.      int print_changes, addit;
  2393. {
  2394.   extern int remember_on_history;
  2395.   extern int history_expansion;
  2396.   extern int history_expand ();
  2397.   char *history_value;
  2398.   char *return_value;
  2399.   int expanded = 0;
  2400.  
  2401.   return_value = line;
  2402.  
  2403.   /* History expand the line.  If this results in no errors, then
  2404.      add that line to the history if ADDIT is non-zero. */
  2405.   if (!history_expansion_inhibited && history_expansion)
  2406.     {
  2407.       expanded = history_expand (line, &history_value);
  2408.  
  2409.       if (expanded)
  2410.     {
  2411.       if (print_changes)
  2412.         fprintf (stderr, "%s\n", history_value);
  2413.  
  2414.       /* If there was an error, return NULL. */
  2415.       if (expanded < 0)
  2416.         {
  2417.           free (history_value);
  2418.  
  2419. #if defined (HISTORY_REEDITING)
  2420.           /* New hack.  We can allow the user to edit the
  2421.          failed history expansion. */
  2422.           re_edit (line);
  2423. #endif /* HISTORY_REEDITING */
  2424.           return ((char *)NULL);
  2425.         }
  2426.     }
  2427.  
  2428.       /* Let other expansions know that return_value can be free'ed,
  2429.      and that a line has been added to the history list.  Note
  2430.      that we only add lines that have something in them. */
  2431.       expanded = 1;
  2432.       return_value = history_value;
  2433.     }
  2434.  
  2435.   if (addit && remember_on_history && *return_value)
  2436.     {
  2437.       extern int history_control;
  2438.  
  2439.       switch (history_control)
  2440.     {
  2441.       case 0:
  2442.         bash_add_history (return_value);
  2443.         break;
  2444.       case 1:
  2445.         if (*return_value != ' ')
  2446.           bash_add_history (return_value);
  2447.         break;
  2448.       case 2:
  2449.         {
  2450.           HIST_ENTRY *temp;
  2451.  
  2452.           using_history ();
  2453.           temp = previous_history ();
  2454.  
  2455.           if (!temp || (strcmp (temp->line, return_value) != 0))
  2456.         bash_add_history (return_value);
  2457.  
  2458.           using_history ();
  2459.         }
  2460.         break;
  2461.     }
  2462.     }
  2463.  
  2464.   if (!expanded)
  2465.     return_value = savestring (line);
  2466.  
  2467.   return (return_value);
  2468. }
  2469.  
  2470.  
  2471. /* Place to remember the token.  We try to keep the buffer
  2472.    at a reasonable size, but it can grow. */
  2473. char *token = (char *)NULL;
  2474.  
  2475. /* Current size of the token buffer. */
  2476. int token_buffer_size = 0;
  2477.  
  2478. /* Command to read_token () explaining what we want it to do. */
  2479. #define READ 0
  2480. #define RESET 1
  2481. #define prompt_is_ps1 \
  2482.       (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
  2483.  
  2484. /* Function for yyparse to call.  yylex keeps track of
  2485.    the last two tokens read, and calls read_token.  */
  2486.  
  2487. yylex ()
  2488. {
  2489.   if (interactive && (!current_token || current_token == '\n'))
  2490.     {
  2491.       /* Before we print a prompt, we might have to check mailboxes.
  2492.      We do this only if it is time to do so. Notice that only here
  2493.      is the mail alarm reset; nothing takes place in check_mail ()
  2494.      except the checking of mail.  Please don't change this. */
  2495.       if (prompt_is_ps1 && time_to_check_mail ())
  2496.     {
  2497.       check_mail ();
  2498.       reset_mail_timer ();
  2499.     }
  2500.  
  2501.       /* Allow the execution of a random command just before the printing
  2502.      of each primary prompt.  If the shell variable PROMPT_COMMAND
  2503.      is set then the value of it is the command to execute. */
  2504.       if (prompt_is_ps1)
  2505.     {
  2506.       char *command_to_execute;
  2507.  
  2508.       command_to_execute = get_string_value ("PROMPT_COMMAND");
  2509.  
  2510.       if (command_to_execute)
  2511.         {
  2512.           extern Function *last_shell_builtin, *this_shell_builtin;
  2513.           extern int last_command_exit_value;
  2514.           Function *temp_last, *temp_this;
  2515.           int temp_exit_value, temp_eof_encountered;
  2516.  
  2517.           temp_last = last_shell_builtin;
  2518.           temp_this = this_shell_builtin;
  2519.           temp_exit_value = last_command_exit_value;
  2520.           temp_eof_encountered = eof_encountered;
  2521.  
  2522.           parse_and_execute
  2523.         (savestring (command_to_execute), "PROMPT_COMMAND");
  2524.  
  2525.           last_shell_builtin = temp_last;
  2526.           this_shell_builtin = temp_this;
  2527.           last_command_exit_value = temp_exit_value;
  2528.           eof_encountered = temp_eof_encountered;
  2529.         }
  2530.     }
  2531.       prompt_again ();
  2532.     }
  2533.  
  2534.   token_before_that = last_read_token;
  2535.   last_read_token = current_token;
  2536.   current_token = read_token (READ);
  2537.   return (current_token);
  2538. }
  2539.  
  2540. /* Called from shell.c when Control-C is typed at top level.  Or
  2541.    by the error rule at top level. */
  2542. reset_parser ()
  2543. {
  2544.   read_token (RESET);
  2545. }
  2546.   
  2547. /* When non-zero, we have read the required tokens
  2548.    which allow ESAC to be the next one read. */
  2549. static int allow_esac_as_next = 0;
  2550.  
  2551. /* When non-zero, accept single '{' as a token itself. */
  2552. static int allow_open_brace = 0;
  2553.  
  2554. /* DELIMITER is the value of the delimiter that is currently
  2555.    enclosing, or zero for none. */
  2556. static int delimiter = 0;
  2557. static int old_delimiter = 0;
  2558.  
  2559. /* When non-zero, an open-brace used to create a group is awaiting a close
  2560.    brace partner. */
  2561. static int open_brace_awaiting_satisfaction = 0;
  2562.  
  2563. /* If non-zero, it is the token that we want read_token to return regardless
  2564.    of what text is (or isn't) present to be read.  read_token resets this. */
  2565. int token_to_read = 0;
  2566.  
  2567. /* Read the next token.  Command can be READ (normal operation) or 
  2568.    RESET (to normalize state). */
  2569. read_token (command)
  2570.      int command;
  2571. {
  2572.   extern int interactive_shell;    /* Whether the current shell is interactive. */
  2573.   int character;        /* Current character. */
  2574.   int peek_char;        /* Temporary look-ahead character. */
  2575.   int result;            /* The thing to return. */
  2576.   WORD_DESC *the_word;        /* The value for YYLVAL when a WORD is read. */
  2577.  
  2578.   if (token_buffer_size < TOKEN_DEFAULT_GROW_SIZE)
  2579.     {
  2580.       if (token)
  2581.     free (token);
  2582.       token = (char *)xmalloc (token_buffer_size = TOKEN_DEFAULT_GROW_SIZE);
  2583.     }
  2584.  
  2585.   if (command == RESET)
  2586.     {
  2587.       delimiter = old_delimiter = 0;
  2588.       open_brace_awaiting_satisfaction = 0;
  2589.       in_case_pattern_list = 0;
  2590.  
  2591. #if defined (ALIAS)
  2592.       if (pushed_string_list)
  2593.     {
  2594.       free_string_list ();
  2595.       pushed_string_list = (STRING_SAVER *)NULL;
  2596.     }
  2597.  
  2598.       if (pending_token_being_expanded)
  2599.     {
  2600.       free (pending_token_being_expanded);
  2601.       pending_token_being_expanded = (char *)NULL;
  2602.     }
  2603.  
  2604.       if (current_token_being_expanded)
  2605.     {
  2606.       free (current_token_being_expanded);
  2607.       current_token_being_expanded = (char *)NULL;
  2608.     }
  2609.  
  2610.       if (expanded_token_stack)
  2611.     {
  2612.       free_expansion_stack ();
  2613.       expanded_token_stack = (EXPANSION_SAVER *)NULL;
  2614.     }
  2615.  
  2616.       expand_next_token = 0;
  2617. #endif /* ALIAS */
  2618.  
  2619.       if (shell_input_line)
  2620.     {
  2621.       free (shell_input_line);
  2622.       shell_input_line = (char *)NULL;
  2623.       shell_input_line_size = shell_input_line_index = 0;
  2624.     }
  2625.       last_read_token = '\n';
  2626.       token_to_read = '\n';
  2627.       return ('\n');
  2628.     }
  2629.  
  2630.   if (token_to_read)
  2631.     {
  2632.       int rt = token_to_read;
  2633.       token_to_read = 0;
  2634.       return (rt);
  2635.     }
  2636.  
  2637. #if defined (ALIAS)
  2638.   /*
  2639.    * Now we can replace current_token_being_expanded with 
  2640.    * pending_token_being_expanded, since the token that would be 
  2641.    * inappropriately compared has already been returned.
  2642.    *
  2643.    * To see why restoring current_token_being_expanded in pop_string ()
  2644.    * could be a problem, consider "alias foo=foo".  Then try to
  2645.    * expand `foo'.  The initial value of current_token_being_expanded is
  2646.    * NULL, so that is what is pushed onto pushed_string_list as the
  2647.    * value of saved_token_being_expanded.  "foo" then becomes shell_input_line.
  2648.    * read_token calls shell_getc for `f', `o', `o', and then shell_getc
  2649.    * hits the end of shell_input_line.  pushed_string_list is not empty
  2650.    * so it gets popped.  If we were to blindly restore
  2651.    * current_token_being_expanded at this point, `foo' would be compared
  2652.    * with a NULL string in the check for recursive expansion, and would
  2653.    * infinitely recurse.
  2654.    */
  2655.   if (pending_token_being_expanded)
  2656.     {
  2657.       if (current_token_being_expanded)
  2658.     free (current_token_being_expanded);
  2659.       current_token_being_expanded = pending_token_being_expanded;
  2660.       pending_token_being_expanded = (char *)NULL;
  2661.     }
  2662.  
  2663.   /* If we hit read_token () and there are no saved strings on the
  2664.      pushed_string_list, then we are no longer currently expanding a
  2665.      token.  This can't be done in pop_stream, because pop_stream
  2666.      may pop the stream before the current token has finished being
  2667.      completely expanded (consider what happens when we alias foo to foo,
  2668.      and then try to expand it). */
  2669.   if (!pushed_string_list && current_token_being_expanded)
  2670.     {
  2671.       free (current_token_being_expanded);
  2672.       current_token_being_expanded = (char *)NULL;
  2673.  
  2674.       if (expanded_token_stack)
  2675.     {
  2676.       free_expansion_stack ();
  2677.       expanded_token_stack = (EXPANSION_SAVER *)NULL;
  2678.     }
  2679.     }
  2680.  
  2681.   /* This is a place to jump back to once we have successfully expanded a
  2682.      token with an alias and pushed the string with push_string () */
  2683. re_read_token:
  2684.  
  2685. #endif /* ALIAS */
  2686.  
  2687.   /* Read a single word from input.  Start by skipping blanks. */
  2688.   while ((character = shell_getc (1)) != EOF && whitespace (character));
  2689.  
  2690.   if (character == EOF)
  2691.     return (yacc_EOF);
  2692.  
  2693.   if (character == '#' && !interactive)
  2694.     {
  2695.       /* A comment.  Discard until EOL or EOF, and then return a newline. */
  2696.       discard_until ('\n');
  2697.       shell_getc (0);
  2698.  
  2699.       /* If we're about to return an unquoted newline, we can go and collect
  2700.      the text of any pending here document. */
  2701.       if (need_here_doc)
  2702.     make_here_document (redirection_needing_here_doc);
  2703.       need_here_doc = 0;
  2704.  
  2705. #if defined (ALIAS)
  2706.       expand_next_token = 0;
  2707. #endif /* ALIAS */
  2708.  
  2709.       return ('\n');
  2710.     }
  2711.  
  2712.   if (character == '\n')
  2713.     {
  2714.       /* If we're about to return an unquoted newline, we can go and collect
  2715.      the text of any pending here document. */
  2716.       if (need_here_doc)
  2717.     make_here_document (redirection_needing_here_doc);
  2718.       need_here_doc = 0;
  2719.  
  2720. #if defined (ALIAS)
  2721.       expand_next_token = 0;
  2722. #endif /* ALIAS */
  2723.  
  2724.       return (character);
  2725.     }
  2726.  
  2727.   if (member (character, "()<>;&|"))
  2728.     {
  2729. #if defined (ALIAS)
  2730.       /* Turn off alias tokenization iff this character sequence would
  2731.      not leave us ready to read a command. */
  2732.       if (character == '<' || character == '>')
  2733.     expand_next_token = 0;
  2734. #endif /* ALIAS */
  2735.  
  2736.       /* Please note that the shell does not allow whitespace to
  2737.      appear in between tokens which are character pairs, such as
  2738.      "<<" or ">>".  I believe this is the correct behaviour. */
  2739.       if (character == (peek_char = shell_getc (1)))
  2740.     {
  2741.       switch (character)
  2742.         {
  2743.           /* If '<' then we could be at "<<" or at "<<-".  We have to
  2744.          look ahead one more character. */
  2745.         case '<':
  2746.           peek_char = shell_getc (1);
  2747.           if (peek_char == '-')
  2748.         return (LESS_LESS_MINUS);
  2749.           else
  2750.         {
  2751.           shell_ungetc (peek_char);
  2752.           return (LESS_LESS);
  2753.         }
  2754.  
  2755.         case '>':
  2756.           return (GREATER_GREATER);
  2757.  
  2758.         case ';':
  2759.           in_case_pattern_list = 1;
  2760. #if defined (ALIAS)
  2761.           expand_next_token = 0;
  2762. #endif /* ALIAS */
  2763.           return (SEMI_SEMI);
  2764.  
  2765.         case '&':
  2766.           return (AND_AND);
  2767.  
  2768.         case '|':
  2769.           return (OR_OR);
  2770.         }
  2771.     }
  2772.       else
  2773.     {
  2774.       if (peek_char == '&')
  2775.         {
  2776.           switch (character)
  2777.         {
  2778.         case '<': return (LESS_AND);
  2779.         case '>': return (GREATER_AND);
  2780.         }
  2781.         }
  2782.       if (character == '<' && peek_char == '>')
  2783.         return (LESS_GREATER);
  2784.       if (character == '>' && peek_char == '|')
  2785.         return (GREATER_BAR);
  2786.       if (peek_char == '>' && character == '&')
  2787.         return (AND_GREATER);
  2788.     }
  2789.       shell_ungetc (peek_char);
  2790.  
  2791.       /* If we look like we are reading the start of a function
  2792.      definition, then let the reader know about it so that
  2793.      we will do the right thing with `{'. */
  2794.       if (character == ')' &&
  2795.       last_read_token == '(' && token_before_that == WORD)
  2796.     {
  2797.       allow_open_brace = 1;
  2798. #if defined (ALIAS)
  2799.       expand_next_token = 0;
  2800. #endif /* ALIAS */
  2801.     }
  2802.  
  2803.       if (in_case_pattern_list && (character == ')'))
  2804.     in_case_pattern_list = 0;
  2805.  
  2806.       return (character);
  2807.     }
  2808.  
  2809.   /* Hack <&- (close stdin) case. */
  2810.   if (character == '-')
  2811.     {
  2812.       switch (last_read_token)
  2813.     {
  2814.     case LESS_AND:
  2815.     case GREATER_AND:
  2816.       return (character);
  2817.     }
  2818.     }
  2819.   
  2820.   /* Okay, if we got this far, we have to read a word.  Read one,
  2821.      and then check it against the known ones. */
  2822.   {
  2823.     /* Index into the token that we are building. */
  2824.     int token_index = 0;
  2825.  
  2826.     /* ALL_DIGITS becomes zero when we see a non-digit. */
  2827.     int all_digits = digit (character);
  2828.  
  2829.     /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
  2830.     int dollar_present = 0;
  2831.  
  2832.     /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
  2833.     int quoted = 0;
  2834.  
  2835.     /* Non-zero means to ignore the value of the next character, and just
  2836.        to add it no matter what. */
  2837.     int pass_next_character = 0;
  2838.  
  2839.     /* Non-zero means parsing a dollar-paren construct.  It is the count of
  2840.        un-quoted closes we need to see. */
  2841.     int dollar_paren_level = 0;
  2842.  
  2843.     /* Non-zero means parsing a dollar-bracket construct ($[...]).  It is
  2844.        the count of un-quoted `]' characters we need to see. */
  2845.     int dollar_bracket_level = 0;
  2846.  
  2847.     /* Another level variable.  This one is for dollar_parens inside of
  2848.        double-quotes. */
  2849.     int delimited_paren_level = 0;
  2850.  
  2851.     for (;;)
  2852.       {
  2853.     if (character == EOF)
  2854.       goto got_token;
  2855.  
  2856.     if (pass_next_character)
  2857.       {
  2858.         pass_next_character = 0;
  2859.         goto got_character;
  2860.       }
  2861.  
  2862.       if (delimiter && character == '\\' && delimiter != '\'')
  2863.     {
  2864.       peek_char = shell_getc (0);
  2865.       if (peek_char != '\\')
  2866.         shell_ungetc (peek_char);
  2867.       else
  2868.         {
  2869.           token[token_index++] = character;
  2870.           goto got_character;
  2871.         }
  2872.     }
  2873.  
  2874.     /* Handle backslashes.  Quote lots of things when not inside of
  2875.        double-quotes, quote some things inside of double-quotes. */
  2876.        
  2877.     if (character == '\\' && delimiter != '\'')
  2878.       {
  2879.         peek_char = shell_getc (0);
  2880.  
  2881.         /* Backslash-newline is ignored in all cases excepting
  2882.            when quoted with single quotes. */
  2883.         if (peek_char == '\n')
  2884.           {
  2885.         character = '\n';
  2886.         goto next_character;
  2887.           }
  2888.         else
  2889.           {
  2890.         shell_ungetc (peek_char);
  2891.  
  2892.         /* If the next character is to be quoted, do it now. */
  2893.         if (!delimiter || delimiter == '`' ||
  2894.             ((delimiter == '"' ) &&
  2895.              (member (peek_char, slashify_in_quotes))))
  2896.           {
  2897.             pass_next_character++;
  2898.             quoted = 1;
  2899.             goto got_character;
  2900.           }
  2901.           }
  2902.       }
  2903.  
  2904.     /* This is a hack, in its present form.  If a backquote substitution
  2905.        appears within double quotes, everything within the backquotes
  2906.        should be read as part of a single word.  Jesus.  Now I see why
  2907.        Korn introduced the $() form. */
  2908.     if (delimiter && delimiter == '"' && character == '`')
  2909.       {
  2910.         old_delimiter = delimiter;
  2911.         delimiter = character;
  2912.         goto got_character;
  2913.       }
  2914.  
  2915.     if (delimiter)
  2916.       {
  2917.         if (character == delimiter)
  2918.           {
  2919.         if (delimited_paren_level)
  2920.           {
  2921. #if defined (NOTDEF)
  2922.             report_error ("Expected ')' before %c", character);
  2923.             return ('\n');
  2924. #else
  2925.             goto got_character;
  2926. #endif /* NOTDEF */
  2927.           }
  2928.  
  2929.         delimiter = 0;
  2930.  
  2931.         if (old_delimiter == '"' && character == '`')
  2932.           {
  2933.             delimiter = old_delimiter;
  2934.             old_delimiter = 0;
  2935.           }
  2936.  
  2937.         goto got_character;
  2938.           }
  2939.       }
  2940.  
  2941.     if (!delimiter || delimiter == '`' || delimiter == '"')
  2942.       {
  2943.         if (character == '$')
  2944.           {
  2945.         peek_char = shell_getc (1);
  2946.         shell_ungetc (peek_char);
  2947.         if (peek_char == '(')
  2948.           {
  2949.             if (!delimiter)
  2950.               dollar_paren_level++;
  2951.             else
  2952.               delimited_paren_level++;
  2953.  
  2954.             pass_next_character++;
  2955.             goto got_character;
  2956.           }
  2957.         else if (peek_char == '[')
  2958.           {
  2959.             if (!delimiter)
  2960.               dollar_bracket_level++;
  2961.  
  2962.             pass_next_character++;
  2963.             goto got_character;
  2964.           }
  2965.           }
  2966.  
  2967.         /* If we are parsing a $() or $[] construct, we need to balance
  2968.            parens and brackets inside the construct.  This whole function
  2969.            could use a rewrite. */
  2970.         if (character == '(')
  2971.           {
  2972.         if (delimiter && delimited_paren_level)
  2973.           delimited_paren_level++;
  2974.  
  2975.         if (!delimiter && dollar_paren_level)
  2976.           dollar_paren_level++;
  2977.           }
  2978.  
  2979.         if (character == '[')
  2980.           {
  2981.         if (!delimiter && dollar_bracket_level)
  2982.           dollar_bracket_level++;
  2983.           }
  2984.  
  2985.         /* This code needs to take into account whether we are inside a
  2986.            case statement pattern list, and whether this paren is supposed
  2987.            to terminate it (hey, it could happen).  It's not as simple
  2988.            as just using in_case_pattern_list, because we're not parsing
  2989.            anything while we're reading a $( ) construct.  Maybe we
  2990.            should move that whole mess into the yacc parser. */
  2991.         if (character == ')')
  2992.           {
  2993.         if (delimiter && delimited_paren_level)
  2994.           delimited_paren_level--;
  2995.  
  2996.         if (!delimiter && dollar_paren_level)
  2997.           {
  2998.             dollar_paren_level--;
  2999.             goto got_character;
  3000.           }
  3001.           }
  3002.  
  3003.         if (character == ']')
  3004.           {
  3005.         if (!delimiter && dollar_bracket_level)
  3006.           {
  3007.             dollar_bracket_level--;
  3008.             goto got_character;
  3009.           }
  3010.           }
  3011.       }
  3012.  
  3013.     if (!dollar_paren_level && !dollar_bracket_level && !delimiter &&
  3014.         member (character, " \t\n;&()|<>"))
  3015.       {
  3016.         shell_ungetc (character);
  3017.         goto got_token;
  3018.       }
  3019.     
  3020.     if (!delimiter)
  3021.       {
  3022.         if (character == '"' || character == '`' || character == '\'')
  3023.           {
  3024.         quoted = 1;
  3025.         delimiter = character;
  3026.         goto got_character;
  3027.           }
  3028.       }
  3029.  
  3030.     if (all_digits) all_digits = digit (character);
  3031.     if (character == '$') dollar_present = 1;
  3032.  
  3033.       got_character:
  3034.  
  3035.     token[token_index++] = character;
  3036.  
  3037.     if (token_index == (token_buffer_size - 1))
  3038.       token = (char *)xrealloc (token, (token_buffer_size
  3039.                         += TOKEN_DEFAULT_GROW_SIZE));
  3040.     {
  3041.       char *decode_prompt_string ();
  3042.  
  3043.     next_character:
  3044.       if (character == '\n' && interactive && bash_input.type != st_string)
  3045.         prompt_again ();
  3046.     }
  3047.     /* We want to remove quoted newlines (that is, a \<newline> pair)
  3048.        unless we are within single quotes or pass_next_character is
  3049.        set (the shell equivalent of literal-next). */
  3050.     character = shell_getc ((delimiter != '\'') && (!pass_next_character));
  3051.       }
  3052.  
  3053.   got_token:
  3054.  
  3055.     token[token_index] = '\0';
  3056.     
  3057.     if ((delimiter || dollar_paren_level || dollar_bracket_level) &&
  3058.     character == EOF)
  3059.       {
  3060.     if (dollar_paren_level && !delimiter)
  3061.       delimiter = ')';
  3062.     else if (dollar_bracket_level && !delimiter)
  3063.       delimiter = ']';
  3064.  
  3065.     report_error ("Unexpected EOF.  Looking for `%c'.", delimiter);
  3066.     return (-1);
  3067.       }
  3068.  
  3069.     if (all_digits)
  3070.       {
  3071.     /* Check to see what thing we should return.  If the last_read_token
  3072.        is a `<', or a `&', or the character which ended this token is
  3073.        a '>' or '<', then, and ONLY then, is this input token a NUMBER.
  3074.        Otherwise, it is just a word, and should be returned as such. */
  3075.  
  3076.     if ((character == '<' || character == '>') ||
  3077.         (last_read_token == LESS_AND ||
  3078.          last_read_token == GREATER_AND))
  3079.       {
  3080.         yylval.number = atoi (token); /* was sscanf (token, "%d", &(yylval.number)); */
  3081.         return (NUMBER);
  3082.       }
  3083.       }
  3084.  
  3085.     /* Handle special case.  IN is recognized if the last token
  3086.        was WORD and the token before that was FOR or CASE. */
  3087.     if ((last_read_token == WORD) &&
  3088.     ((token_before_that == FOR) || (token_before_that == CASE)) &&
  3089.     (STREQ (token, "in")))
  3090.       {
  3091.     if (token_before_that == CASE)
  3092.       {
  3093.         in_case_pattern_list = 1;
  3094.         allow_esac_as_next++;
  3095.       }
  3096.     return (IN);
  3097.       }
  3098.  
  3099.     /* Ditto for DO in the FOR case. */
  3100.     if ((last_read_token == WORD) && (token_before_that == FOR) &&
  3101.     (STREQ (token, "do")))
  3102.       return (DO);
  3103.  
  3104.     /* Ditto for ESAC in the CASE case. 
  3105.        Specifically, this handles "case word in esac", which is a legal
  3106.        construct, certainly because someone will pass an empty arg to the
  3107.        case construct, and we don't want it to barf.  Of course, we should
  3108.        insist that the case construct has at least one pattern in it, but
  3109.        the designers disagree. */
  3110.     if (allow_esac_as_next)
  3111.       {
  3112.     allow_esac_as_next--;
  3113.     if (STREQ (token, "esac"))
  3114.       {
  3115.         in_case_pattern_list = 0;
  3116.         return (ESAC);
  3117.       }
  3118.       }
  3119.  
  3120.     /* Ditto for `{' in the FUNCTION case. */
  3121.     if (allow_open_brace)
  3122.       {
  3123.     allow_open_brace = 0;
  3124.     if (STREQ (token, "{"))
  3125.       {
  3126.         open_brace_awaiting_satisfaction++;
  3127.         return ('{');
  3128.       }
  3129.       }
  3130.  
  3131. #if defined (ALIAS)
  3132.  
  3133. #define command_token_position(token) \
  3134.     ((token) != SEMI_SEMI && reserved_word_acceptable (token))
  3135.  
  3136.     /* OK, we have a token.  Let's try to alias expand it, if (and only if)
  3137.        it's eligible. 
  3138.  
  3139.        It is eligible for expansion if the shell is in interactive mode, and
  3140.        the token is unquoted and the last token read was a command
  3141.        separator (or expand_next_token is set), and we are currently
  3142.        processing an alias (pushed_string_list is non-empty) and this
  3143.        token is not the same as the current or any previously
  3144.        processed alias.
  3145.  
  3146.        Special cases that disqualify:
  3147.      In a pattern list in a case statement (in_case_pattern_list). */
  3148.     if (interactive_shell && !quoted && !in_case_pattern_list &&
  3149.     (command_token_position (last_read_token) || expand_next_token))
  3150.       {
  3151.     char *alias_expand_word (), *expanded;
  3152.     if (current_token_being_expanded &&
  3153.          ((STREQ (token, current_token_being_expanded)) ||
  3154.           (token_has_been_expanded (token))))
  3155.       goto no_expansion;
  3156.  
  3157.     expanded = alias_expand_word (token);
  3158.     if (expanded)
  3159.       {
  3160.         int len = strlen (expanded), expand_next;
  3161.         char *temp;
  3162.  
  3163.         /* Erase the current token. */
  3164.         token_index = 0;
  3165.  
  3166.         expand_next = (expanded[len - 1] == ' ') ||
  3167.               (expanded[len - 1] == '\t');
  3168.  
  3169.         temp = savestring (token);
  3170.         push_string (expanded, expand_next, temp);
  3171.         goto re_read_token;
  3172.       }
  3173.     else
  3174.       /* This is an eligible token that does not have an expansion. */
  3175. no_expansion:
  3176.       expand_next_token = 0;
  3177.       }
  3178.     else
  3179.       {
  3180.     expand_next_token = 0;
  3181.       }
  3182. #endif /* ALIAS */
  3183.  
  3184.     /* Check to see if it is a reserved word.  */
  3185.     if (!dollar_present && !quoted &&
  3186.     reserved_word_acceptable (last_read_token))
  3187.       {
  3188.     int i;
  3189.     for (i = 0; word_token_alist[i].word != (char *)NULL; i++)
  3190.       if (STREQ (token, word_token_alist[i].word))
  3191.         {
  3192.           if (in_case_pattern_list && (word_token_alist[i].token != ESAC))
  3193.         break;
  3194.  
  3195.           if (word_token_alist[i].token == ESAC)
  3196.         in_case_pattern_list = 0;
  3197.  
  3198.           if (word_token_alist[i].token == '{')
  3199.         open_brace_awaiting_satisfaction++;
  3200.  
  3201.           return (word_token_alist[i].token);
  3202.         }
  3203.       }
  3204.  
  3205.     /* What if we are attempting to satisfy an open-brace grouper? */
  3206.     if (open_brace_awaiting_satisfaction && strcmp (token, "}") == 0)
  3207.       {
  3208.     open_brace_awaiting_satisfaction--;
  3209.     return ('}');
  3210.       }
  3211.  
  3212.     the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
  3213.     the_word->word = (char *)xmalloc (1 + strlen (token));
  3214.     strcpy (the_word->word, token);
  3215.     the_word->dollar_present = dollar_present;
  3216.     the_word->quoted = quoted;
  3217.     the_word->assignment = assignment (token);
  3218.  
  3219.     yylval.word = the_word;
  3220.     result = WORD;
  3221.     if (last_read_token == FUNCTION)
  3222.       allow_open_brace = 1;
  3223.   }
  3224.   return (result);
  3225. }
  3226.  
  3227. #if defined (NOTDEF)        /* Obsoleted function no longer used. */
  3228. /* Return 1 if this token is a legal shell `identifier'; that is, it consists
  3229.    solely of letters, digits, and underscores, and does not begin with a 
  3230.    digit. */
  3231. legal_identifier (name)
  3232.      char *name;
  3233. {
  3234.   register char *s;
  3235.  
  3236.   if (!name || !*name)
  3237.     return (0);
  3238.  
  3239.   if (digit (*name))
  3240.     return (0);
  3241.  
  3242.   for (s = name; s && *s; s++)
  3243.     {
  3244.       if (!isletter (*s) && !digit (*s) && (*s != '_'))
  3245.     return (0);
  3246.     }
  3247.   return (1);
  3248. }
  3249. #endif /* NOTDEF */
  3250.  
  3251. /* Return 1 if TOKEN is a token that after being read would allow
  3252.    a reserved word to be seen, else 0. */
  3253. static int
  3254. reserved_word_acceptable (token)
  3255.      int token;
  3256. {
  3257.   if (member (token, "\n;()|&{") ||
  3258.       token == AND_AND ||
  3259.       token == BANG ||
  3260.       token == DO ||
  3261.       token == ELIF ||
  3262.       token == ELSE ||
  3263.       token == IF ||
  3264.       token == OR_OR ||
  3265.       token == SEMI_SEMI ||
  3266.       token == THEN ||
  3267.       token == UNTIL ||
  3268.       token == WHILE ||
  3269.       token == 0)
  3270.     return (1);
  3271.   else
  3272.     return (0);
  3273. }
  3274.  
  3275. #if defined (READLINE)
  3276. /* Called after each time readline is called.  This insures that whatever
  3277.    the new prompt string is gets propagated to readline's local prompt
  3278.    variable. */
  3279. reset_readline_prompt ()
  3280. {
  3281.   if (prompt_string_pointer && *prompt_string_pointer)
  3282.     {
  3283.       char *temp_prompt, *decode_prompt_string ();
  3284.  
  3285.       temp_prompt = decode_prompt_string (*prompt_string_pointer);
  3286.  
  3287.       if (!temp_prompt)
  3288.     temp_prompt = savestring ("");
  3289.  
  3290.       if (current_readline_prompt)
  3291.     free (current_readline_prompt);
  3292.  
  3293.       current_readline_prompt = temp_prompt;
  3294.     }
  3295. }
  3296. #endif
  3297.  
  3298. /* A list of tokens which can be followed by newlines, but not by
  3299.    semi-colons.  When concatenating multiple lines of history, the
  3300.    newline separator for such tokens is replaced with a space. */
  3301. int no_semi_successors[] = {
  3302.   '\n', '{', '(', ')', ';',
  3303.   CASE, DO, ELSE, IF, IN, SEMI_SEMI, THEN, UNTIL, WHILE,
  3304.   0
  3305. };
  3306.  
  3307. /* Add a line to the history list.
  3308.    The variable COMMAND_ORIENTED_HISTORY controls the style of history
  3309.    remembering;  when non-zero, and LINE is not the first line of a
  3310.    complete parser construct, append LINE to the last history line instead
  3311.    of adding it as a new line. */
  3312. bash_add_history (line)
  3313.      char *line;
  3314. {
  3315.   extern int command_oriented_history;
  3316.   int add_it = 1;
  3317.  
  3318.   if (command_oriented_history && current_command_line_count > 1)
  3319.     {
  3320.       register int offset;
  3321.       register HIST_ENTRY *current, *old;
  3322.       char *chars_to_add, *new_line;
  3323.  
  3324.       /* If we are not within a delimited expression, try to be smart
  3325.      about which separators can be semi-colons and which must be
  3326.      newlines. */
  3327.       if (!delimiter)
  3328.     {
  3329.       register int i;
  3330.  
  3331.       chars_to_add = (char *)NULL;
  3332.  
  3333.       for (i = 0; no_semi_successors[i]; i++)
  3334.         {
  3335.           if (token_before_that == no_semi_successors[i])
  3336.         {
  3337.           chars_to_add = " ";
  3338.           break;
  3339.         }
  3340.         }
  3341.       if (!chars_to_add)
  3342.         chars_to_add = "; ";
  3343.     }
  3344.       else
  3345.     chars_to_add = "\n";
  3346.  
  3347.       using_history ();
  3348.  
  3349.       current = previous_history ();
  3350.  
  3351.       if (current)
  3352.     {
  3353.       offset = where_history ();
  3354.       new_line = (char *) xmalloc (1
  3355.                        + strlen (current->line)
  3356.                        + strlen (line)
  3357.                        + strlen (chars_to_add));
  3358.       sprintf (new_line, "%s%s%s", current->line, chars_to_add, line);
  3359.       old = replace_history_entry (offset, new_line, current->data);
  3360.       free (new_line);
  3361.  
  3362.       if (old)
  3363.         {
  3364.           /* Note that the old data is not freed, since it was simply
  3365.          copied to the new history entry. */
  3366.           if (old->line)
  3367.         free (old->line);
  3368.  
  3369.           free (old);
  3370.         }
  3371.       add_it = 0;
  3372.     }
  3373.     }
  3374.  
  3375.   if (add_it)
  3376.     {
  3377.       extern int history_lines_this_session;
  3378.  
  3379.       add_history (line);
  3380.       history_lines_this_session++;
  3381.     }
  3382.   using_history ();
  3383. }
  3384.  
  3385. /* Issue a prompt, or prepare to issue a prompt when the next character
  3386.    is read. */
  3387. prompt_again ()
  3388. {
  3389.   char *temp_prompt, *decode_prompt_string ();
  3390.  
  3391.   ps1_prompt = get_string_value ("PS1");
  3392.   ps2_prompt = get_string_value ("PS2");
  3393.  
  3394.   if (!prompt_string_pointer)
  3395.     prompt_string_pointer = &ps1_prompt;
  3396.  
  3397.   if (*prompt_string_pointer)
  3398.     temp_prompt = decode_prompt_string (*prompt_string_pointer);
  3399.   else
  3400.     temp_prompt = savestring ("");
  3401.  
  3402.   current_prompt_string = *prompt_string_pointer;
  3403.   prompt_string_pointer = &ps2_prompt;
  3404.  
  3405. #if defined (READLINE)
  3406.   if (!no_line_editing)
  3407.     {
  3408.       if (current_readline_prompt)
  3409.     free (current_readline_prompt);
  3410.       
  3411.       current_readline_prompt = temp_prompt;
  3412.     }
  3413.   else
  3414. #endif    /* READLINE */
  3415.     {
  3416.       if (interactive)
  3417.     {
  3418.       fprintf (stderr, "%s", temp_prompt);
  3419.       fflush (stderr);
  3420.     }
  3421.       free (temp_prompt);
  3422.     }
  3423. }
  3424.  
  3425. #include "maxpath.h"
  3426.  
  3427. /* Return a string which will be printed as a prompt.  The string
  3428.    may contain special characters which are decoded as follows:
  3429.    
  3430.     \t    the time
  3431.     \d    the date
  3432.     \n    CRLF
  3433.     \s    the name of the shell
  3434.     \w    the current working directory
  3435.     \W    the last element of PWD
  3436.     \u    your username
  3437.     \h    the hostname
  3438.     \#    the command number of this command
  3439.     \!    the history number of this command
  3440.     \$    a $ or a # if you are root
  3441.     \<octal> character code in octal
  3442.     \\    a backslash
  3443. */
  3444. #include <sys/param.h>
  3445. #include <time.h>
  3446.  
  3447. #define PROMPT_GROWTH 50
  3448. char *
  3449. decode_prompt_string (string)
  3450.      char *string;
  3451. {
  3452.   int result_size = PROMPT_GROWTH;
  3453.   int result_index = 0;
  3454.   char *result = (char *)xmalloc (PROMPT_GROWTH);
  3455.   int c;
  3456.   char *temp = (char *)NULL;
  3457.  
  3458.   result[0] = 0;
  3459.   while (c = *string++)
  3460.     {
  3461.       if (c == '\\')
  3462.     {
  3463.       c = *string;
  3464.  
  3465.       switch (c)
  3466.         {
  3467.         case '0':
  3468.         case '1':
  3469.         case '2':
  3470.         case '3':
  3471.         case '4':
  3472.         case '5':
  3473.         case '6':
  3474.         case '7':
  3475.           {
  3476.         char octal_string[4];
  3477.         int n;
  3478.  
  3479.         strncpy (octal_string, string, 3);
  3480.         octal_string[3] = '\0';
  3481.  
  3482.         n = read_octal (octal_string);
  3483.  
  3484.         temp = savestring ("\\");
  3485.         if (n != -1)
  3486.           {
  3487.             string += 3;
  3488.             temp[0] = n;
  3489.           }
  3490.  
  3491.         c = 0;
  3492.         goto add_string;
  3493.           }
  3494.       
  3495.         case 't':
  3496.         case 'd':
  3497.           /* Make the current time/date into a string. */
  3498.           {
  3499.         long the_time = time (0);
  3500.         char *ttemp = ctime (&the_time);
  3501.         temp = savestring (ttemp);
  3502.  
  3503.         if (c == 't')
  3504.           {
  3505.             strcpy (temp, temp + 11);
  3506.             temp[8] = '\0';
  3507.           }
  3508.         else
  3509.           temp[10] = '\0';
  3510.  
  3511.         goto add_string;
  3512.           }
  3513.  
  3514.         case 'n':
  3515.           if (!no_line_editing)
  3516.         temp = savestring ("\r\n");
  3517.           else
  3518.         temp = savestring ("\n");
  3519.           goto add_string;
  3520.  
  3521.         case 's':
  3522.           {
  3523.         extern char *shell_name;
  3524.         extern char *base_pathname ();
  3525.  
  3526.         temp = base_pathname (shell_name);
  3527.         temp = savestring (temp);
  3528.         goto add_string;
  3529.           }
  3530.     
  3531.         case 'w':
  3532.         case 'W':
  3533.           {
  3534.         /* Use the value of PWD because it is much more effecient. */
  3535. #define EFFICIENT
  3536. #ifdef EFFICIENT
  3537.         char *polite_directory_format (), t_string[MAXPATHLEN];
  3538.  
  3539.         temp = get_string_value ("PWD");
  3540.  
  3541.         if (!temp)
  3542.           getwd (t_string);
  3543.         else
  3544.           strcpy (t_string, temp);
  3545. #else
  3546.         getwd (t_string);
  3547. #endif    /* EFFICIENT */
  3548.  
  3549.         if (c == 'W')
  3550.           {
  3551.             char *dir = (char *)rindex (t_string, '/');
  3552.             if (dir && dir != t_string)
  3553.               strcpy (t_string, dir + 1);
  3554.             temp = savestring (t_string);
  3555.           }
  3556.         else
  3557.           temp = savestring (polite_directory_format (t_string));
  3558.         goto add_string;
  3559.           }
  3560.       
  3561.         case 'u':
  3562.           {
  3563.         extern char *current_user_name;
  3564.         temp = savestring (current_user_name);
  3565.  
  3566.         goto add_string;
  3567.           }
  3568.  
  3569.         case 'h':
  3570.           {
  3571.         extern char *current_host_name;
  3572.         char *t_string;
  3573.  
  3574.         temp = savestring (current_host_name);
  3575.         if (t_string = (char *)index (temp, '.'))
  3576.           *t_string = '\0';
  3577.         
  3578.         goto add_string;
  3579.           }
  3580.  
  3581.         case '#':
  3582.           {
  3583.         extern int current_command_number;
  3584.         char number_buffer[20];
  3585.         sprintf (number_buffer, "%d", current_command_number);
  3586.         temp = savestring (number_buffer);
  3587.         goto add_string;
  3588.           }
  3589.  
  3590.         case '!':
  3591.           {
  3592.         extern int history_base, where_history ();
  3593.         char number_buffer[20];
  3594.  
  3595.         using_history ();
  3596.         if (get_string_value ("HISTSIZE"))
  3597.           sprintf (number_buffer, "%d",
  3598.                history_base + where_history ());
  3599.         else
  3600.           strcpy (number_buffer, "!");
  3601.         temp = savestring (number_buffer);
  3602.         goto add_string;
  3603.           }
  3604.  
  3605.         case '$':
  3606.           temp = savestring (geteuid () == 0 ? "#" : "$");
  3607.           goto add_string;
  3608.  
  3609.         case '\\':
  3610.           temp = savestring ("\\");
  3611.           goto add_string;
  3612.  
  3613.         default:
  3614.           temp = savestring ("\\ ");
  3615.           temp[1] = c;
  3616.  
  3617.         add_string:
  3618.           if (c)
  3619.         string++;
  3620.           result =
  3621.         (char *)sub_append_string (temp, result,
  3622.                        &result_index, &result_size);
  3623.           temp = (char *)NULL; /* Free ()'ed in sub_append_string (). */
  3624.           result[result_index] = '\0';
  3625.           break;
  3626.         }
  3627.     }
  3628.       else
  3629.     {
  3630.       while (3 + result_index > result_size)
  3631.         result = (char *)xrealloc (result, result_size += PROMPT_GROWTH);
  3632.  
  3633.       result[result_index++] = c;
  3634.       result[result_index] = '\0';
  3635.     }
  3636.     }
  3637.  
  3638.   /* I don't really think that this is a good idea.  Do you? */
  3639.   if (!find_variable ("NO_PROMPT_VARS"))
  3640.     {
  3641.       WORD_LIST *expand_string (), *list;
  3642.       char *string_list ();
  3643.  
  3644.       list = expand_string (result, 1);
  3645.       free (result);
  3646.       result = string_list (list);
  3647.       dispose_words (list);
  3648.     }
  3649.  
  3650.   return (result);
  3651. }
  3652.  
  3653. /* Report a syntax error, and restart the parser.  Call here for fatal
  3654.    errors. */
  3655. yyerror ()
  3656. {
  3657.   report_syntax_error ((char *)NULL);
  3658.   reset_parser ();
  3659. }
  3660.  
  3661. /* Report a syntax error with line numbers, etc.
  3662.    Call here for recoverable errors.  If you have a message to print,
  3663.    then place it in MESSAGE, otherwise pass NULL and this will figure
  3664.    out an appropriate message for you. */
  3665. report_syntax_error (message)
  3666.      char *message;
  3667. {
  3668.   if (message)
  3669.     {
  3670.       if (!interactive)
  3671.     {
  3672.       char *name = bash_input.name ? bash_input.name : "stdin";
  3673.       report_error ("%s:%d: `%s'", name, line_number, message);
  3674.     }
  3675.       else
  3676.     report_error ("%s", message);
  3677.  
  3678.       return;
  3679.     }
  3680.  
  3681.   if (shell_input_line && *shell_input_line)
  3682.     {
  3683.       char *error_token, *t = shell_input_line;
  3684.       register int i = shell_input_line_index;
  3685.       int token_end = 0;
  3686.  
  3687.       if (!t[i] && i)
  3688.     i--;
  3689.  
  3690.       while (i && (t[i] == ' ' || t[i] == '\t' || t[i] == '\n'))
  3691.     i--;
  3692.  
  3693.       if (i)
  3694.     token_end = i + 1;
  3695.  
  3696.       while (i && !member (t[i], " \n\t;|&"))
  3697.     i--;
  3698.  
  3699.       while (i != token_end && member (t[i], " \n\t"))
  3700.     i++;
  3701.  
  3702.       if (token_end)
  3703.     {
  3704.       error_token = (char *)alloca (1 + (token_end - i));
  3705.       strncpy (error_token, t + i, token_end - i);
  3706.       error_token[token_end - i] = '\0';
  3707.  
  3708.       report_error ("syntax error near `%s'", error_token);
  3709.     }
  3710.       else if ((i == 0) && (token_end == 0))    /* a 1-character token */
  3711.     {
  3712.       error_token = (char *) alloca (2);
  3713.       strncpy(error_token, t + i, 1);
  3714.       error_token[1] = '\0';
  3715.  
  3716.       report_error ("syntax error near `%s'", error_token);
  3717.     }
  3718.  
  3719.       if (!interactive)
  3720.     {
  3721.       char *temp = savestring (shell_input_line);
  3722.       char *name = bash_input.name ? bash_input.name : "stdin";
  3723.       int l = strlen (temp);
  3724.  
  3725.       while (l && temp[l - 1] == '\n')
  3726.         temp[--l] = '\0';
  3727.  
  3728.       report_error ("%s:%d: `%s'", name, line_number, temp);
  3729.       free (temp);
  3730.     }
  3731.     }
  3732.   else
  3733.     report_error ("Syntax error");
  3734. }
  3735.  
  3736. /* ??? Needed function. ??? We have to be able to discard the constructs
  3737.    created during parsing.  In the case of error, we want to return
  3738.    allocated objects to the memory pool.  In the case of no error, we want
  3739.    to throw away the information about where the allocated objects live.
  3740.    (dispose_command () will actually free the command. */
  3741. discard_parser_constructs (error_p)
  3742.      int error_p;
  3743. {
  3744. /*   if (error_p) {
  3745.      fprintf (stderr, "*");
  3746.   } */
  3747. }
  3748.    
  3749. /* Do that silly `type "bye" to exit' stuff.  You know, "ignoreeof". */
  3750.  
  3751. /* The number of times that we have encountered an EOF character without
  3752.    another character intervening.  When this gets above the limit, the
  3753.    shell terminates. */
  3754. int eof_encountered = 0;
  3755.  
  3756. /* The limit for eof_encountered. */
  3757. int eof_encountered_limit = 10;
  3758.  
  3759. /* If we have EOF as the only input unit, this user wants to leave
  3760.    the shell.  If the shell is not interactive, then just leave.
  3761.    Otherwise, if ignoreeof is set, and we haven't done this the
  3762.    required number of times in a row, print a message. */
  3763. handle_eof_input_unit ()
  3764. {
  3765.   extern int login_shell, EOF_Reached;
  3766.  
  3767.   if (interactive)
  3768.     {
  3769.       /* If the user wants to "ignore" eof, then let her do so, kind of. */
  3770.       if (find_variable ("ignoreeof") || find_variable ("IGNOREEOF"))
  3771.     {
  3772.       if (eof_encountered < eof_encountered_limit)
  3773.         {
  3774.           fprintf (stderr, "Use \"%s\" to leave the shell.\n",
  3775.                login_shell ? "logout" : "exit");
  3776.           eof_encountered++;
  3777.           /* Reset the prompt string to be $PS1. */
  3778.           prompt_string_pointer = (char **)NULL;
  3779.           prompt_again ();
  3780.           last_read_token = current_token = '\n';
  3781.           return;
  3782.         } 
  3783.     }
  3784.  
  3785.       /* In this case EOF should exit the shell.  Do it now. */
  3786.       reset_parser ();
  3787.       exit_builtin ((WORD_LIST *)NULL);
  3788.     }
  3789.   else
  3790.     {
  3791.       /* We don't write history files, etc., for non-interactive shells. */
  3792.       EOF_Reached = 1;
  3793.     }
  3794. }
  3795.